在golang是init是一个非常特殊的函数,它一般用于初始化全局变量,之所以说特殊,是因为有它有如下与普通函数的不同点:
init函数会在main函数执行前被Golang隐式自动调用,且我们不能主动调用init函数
一个go文件可以拥有多个init函数
通过一个例子理解上面两点:

通过上面例子,我们得知:
init函数是可选的
init函数的定义没有入参也没有出参
一个源文件可以有多个init函数,执行顺序取决于出现的顺序
不允许主动调用init函数,是允许声明多个init函数的原因
一般使用init函数来初始化无法在编译期间就确定的全局变量,比如一个变量需要从环境变量初始化:

ok,到这我们完全清楚了单文件中nit的执行顺序,下面继续深入
单个包中的init执行顺序来做个实验,目录结构是这样的:

test/a/a.go:

test/a/b.go:

test/a/c.go:

test/main.go:

然后运行结果是:

结论:
在main包中导入别的包时,会优先执行导入包中的init函数,再执行main包的init函数
同一个包中不同文件的init函数的执行顺序,是根据文件名的先后顺序来确定的
再做一次实验,在上面的基础上,新增一个包b,结构变成这样:

test/b/a.go:

改动下test/a/b.go内容,在其中导入b包:

然后结果是:

结论:
当递归导入包时,init函数的执行顺序也是递归的
其实在第一次实验的时候已见端倪,因为我们在main包里导入a包,确实也是a包中init函数执行完再到main包的init函数执行
同时导入多个包的时init的执行顺序目录结构依然和第二次实验一致
把test/a/b.go文件中的导入b包取消掉,变回实验一的内容:

然后在test/main.go导入b包:

结果是:

先执行了a包init,随后执行b包init
把a与b包的导入顺序互换下:

执行结果是:

先执行了b包init,再执行a包init
结论:
在同一个文件中导入不同包时,包的init执行顺序跟导入的顺序一致
ok,到此,终于把init的执行顺序给整得明明白白了
撒花~