golang的程序执行时会自动触发包内部的init()函数的调用,该函数没有参数,也没有返回值,不能被主动调用。
包初始化执行顺序:全局声明->init()->main()函数。
在运行时,不在同一个文件导入的包调用顺序是被最后导入的包会最先初始化并调用其init()函数,如果在同一个文件被导入的包,那么就按导入顺序执行。
//main import
import (
"fmt"
"go_init_demo/pkg1"
"go_init_demo/pkg2"
"go_init_demo/pkg3"
)
//pkg1 import
import (
"fmt"
"go_init_demo/pkg2"
)
如上,在main中按顺序引入了pkg1,2,3包,但是pkg1里面引入了pkg2,最终的执行顺序。
this pkg2 init
this pkg1 init
this pkg1 tool init//因为pkg2里面有两个文件,都存在init()函数
this pkg3 init
同一个包可以有多个init()函数,按照如果是同一个文件,它们在源代码中的顺序被调用。
func init() {
fmt.Println("main init")
}
func init() {
fmt.Println("main init1")
}
//输出
main init
main init1
如果同一个包被拆分为多个文件,那么每个文件可以包含一个 init 函数。这些 init 函数的执行顺序是无法保证的,如上面说的pkg2。
因此,init()函数常用于执行一些初始化操作,例如初始化全局变量、注册驱动程序、加载配置文件等。它可以用来确保在程序运行前,必要的初始化工作已经完成。但是要特别注意循环导入问题:循环导入是指两个或多个包之间相互导入的情况。在循环导入的情况下,init 函数的执行顺序可能会变得复杂,并且可能导致编译错误。应该避免出现循环导入的情况。
发表评论