kevinyan815/gocookbook

Go应用初始化工作的执行顺序

kevinyan815 opened this issue · 1 comments

Go应用程序的初始化是在单一的goroutine中执行的。对于包这一级别的初始化来说,**在一个包里会先进行包级别变量的初始化。一个包下可以有多个init函数,每个文件也可以有多个init 函数,多个 init 函数按照它们的文件名顺序逐个初始化。但是程序不可能把所有代码都放在一个包里,通常都是会引入很多包。如果main包引入了pkg1包,pkg1包本身又导入了包pkg2,那么应用程序的初始化会按照什么顺序来执行呢?

对于这个初始化过程我粗略的画了一个示意图,理解起来更直观些。

图的上半部分表示了main包导入了pkg1包,pkg1包又导入了pkg2包这样一个包之间的依赖关系。图的下班部分表示了,这个应用初始化时初始化工作的执行时间顺序,从被导入的最深层包开始进行初始化,层层递出最后到main包,每个包内部的初始化程序依然是先执行包变量初始化再进行init函数的执行。

可以通过这个程序进一步论证上面的结论,程序执行后返回的结果如下,初始化顺序正是和我们预想的一样。

init P2_v1 : 20
init P2_v2 : 30
init func in pkg2
init P1_v1 : 30
init P1_v2 : 40
init func in pkg1
init M_v1 : 50
init M_v2 : 40
init1 func in main
init2 func in main
main func in main

关于Go程序初始化init函数的六个特点:

  • 包级别变量的初始化先于包内init函数的执行。

  • 一个包下可以有多个init函数,每个文件也可以有多个init 函数。

  • 多个 init 函数按照它们的文件名顺序逐个初始化。

  • 应用初始化时初始化工作的顺序是,从被导入的最深层包开始进行初始化,层层递出最后到main包。

  • 不管包被导入多少次,包内的init函数只会执行一次。

  • 应用在所有初始化工作完成后才会执行main函数。

更详细的解释,查看文章:Go语言init函数你必须记住的六个特征

图片太模糊了,看不清