Go init函数
Go语言中init函数用于包(package)的初始化,该函数是go语言的一个重要特性。
包初始化
如果需要使用一个导入的包,首先要对这个包进行初始化,这一步在main
函数执行之前,由runtime
来完成,分以下步骤:
- 初始化导入的包;
- 初始化包中的变量;
- 执行包中的init函数。
如果一个包被导入了多次,也只会执行一次包的初始化。
Go
中一个包中可以包含很多文件,那么变量的初始化顺序与各个包的init函数执行顺序又是怎样的呢?
首先,runtime的初始化依赖机制会启动,当初始化依赖机制计算完成后,就需要决定a.go和z.go中的变量谁先初始化,这取决于呈现给编译器的文件顺序,一般来说是按文件名的字典序,但是变量间或各个包间有依赖需要另外讨论。如果z.go先被传到build系统,那么z.go的变量初始化就比a.go先一步完成。
同一个包中,变量的初始化顺序是按文件名的字典序,但同时runtime也会解析变量间依赖关系,没有依赖的变量最先初始化,init函数的执行顺序也同理。
init函数作用
- 初始化变量
- 程序运行前的注册,例如decoder,parser的注册
- 检查和修复程序状态
- 运行只需计算一次的模块,像sync.once的作用
- 其他
特性
- init函数先于main函数自动执行,不能被其他函数调用;
- init函数没有输入参数、返回值;
- 每个包可以有多个init函数;
- 包的每个源文件也可以有多个init函数,这点比较特殊;
- 同一个包的init执行顺序,golang没有明确定义,编程时要注意程序不要依赖这个执行顺序;
- 不同包的init函数按照包导入的依赖关系决定执行顺序。