背景介绍
如果你的项目中有一些需要初始化,而这些初始化又是通过 init()
来执行的,但是 init()
里面有一些相互依赖,你如何保证你的执行是可行的呢?
可能出现的问题
你在 init()
使用时,可能会有一些值是需要提前初始化的,否则会出现 nil 报错的问题。
init 初始化的规则是怎样的呢?
怎么解决呢?
可以使用 _ "github.com/xxx/xxx"
引入包,但是不使用来解决
附翻译
init相关注意如下:
- 一个包可以出线多个init函数,一个源文件也可以包含多个init函数(Multiple such functions may be defined, even within a single source file. )。
- init函数在代码中不能被显示调用、不能被引用(赋值给函数变量),否则出现编译错误(The init identifier is not declared and thus init functions cannot be referred to from anywhere in a program. )。
- 如果当前包包含多个依赖包(import),则先初始化依赖包(If a package has imports, the imported packages are initialized before initializing the package itself. )。
- 如果当前包有多个init函数,首先按照源文件名的字典序从前往后执行,若一个文件中出现多个init,则按照出现顺序从前往后执行(initialized by assigning initial values to all its package-level variables followed by calling all init functions in the order they appear in the source, possibly in multiple files, as presented to the compiler.)。
- 一个包被引用多次,如 A import B,C import B,A import C,B被引用多次,但B包只会初始化一次( If multiple packages import a package, the imported package will be initialized only once. )。
- 引入包,不可出现死循坏。即A import B,B import A,这种情况编译失败( The importing of packages, by construction, guarantees that there can be no cyclic initialization dependencies. )。
- 包级别的变量初始化、init函数的执行,这两个操作会在goruntine 自己调用,且顺序调用,一次一个包(Package initialization—variable initialization and the invocation of init functions—happens in a single goroutine, sequentially, one package at a time.)。
- 一个init函数里可能会启动其它goroutine,即在初始化的同时启动新的goroutine。然而,初始化依旧是顺序的,即只有上一个init执行完毕,下一个才会开始( An init function may launch other goroutines, which can run concurrently with the initialization code. However, initialization always sequences the init functions: it will not invoke the next one until the previous one has returned.)。
参考资料
- When is the init() function run?
- The init function
- init functions in Go
- go语言的初始化顺序,包,变量,init - 这一篇文章写的很不错。
- The Go init Function
茶歇驿站
一个可以让你停下来看一看,在茶歇之余给你帮助的小站,这里的内容主要是后端技术,个人管理,团队管理,以及其他个人杂想。