gocookbook icon indicating copy to clipboard operation
gocookbook copied to clipboard

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

Open kevinyan815 opened this issue 4 years ago • 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函数你必须记住的六个特征

kevinyan815 avatar Nov 20 '20 07:11 kevinyan815

图片太模糊了,看不清

yyMoming avatar Nov 10 '23 15:11 yyMoming