在一个 go 程序中一般包含:包、常量、变量、init()、main()等元素,若是同时存在多个包,包之间存在依赖关系,每一个包中存在多个 init 函数,每一个文件中存在多个 init 函数。函数
包的执行顺序
- 在 main 包中的 go 文件默认老是会被执行
- 同包下的不一样 go 文件,按照文件名“从小到大”排序顺序执行
- 其余的包只有被 main 包 import 才会执行,按照 import 的前后顺序执行
- 被递归 import 的包的初始化顺序与 import 顺序相反,例如:导入顺序 main –> A –> B –> C,则初始化顺序为 C –> B –> A –> main
- 一个包被其它多个包 import,但只能被初始化一次
- main 包老是被最后一个初始化,由于它老是依赖别的包
- 避免出现循环 import,例如:A –> B –> C –> A
go 程序的初始化顺序见下图:blog

init 和 main 函数
init()、main() 是 go 语言中的保留函数,两个函数在 go 语言中的区别以下:
相同点:排序
- 两个函数在定义时不能有任何的参数和返回值
- 该函数只能由 go 程序自动调用,不能够被引用
不一样点:递归
- init 能够应用于任意包中,且能够重复定义多个。
- main 函数只能用于 main 包中,且只能定义一个。
两个函数的执行顺序:字符串
- 对同一个 go 文件的 init( ) 调用顺序是从上到下的
- 对同一个 package 中的不一样文件,将文件名按字符串进行“从小到大”排序,以后顺序调用各文件中的init()函数
- 对于不一样的 package,若是不相互依赖的话,按照 main 包中 import 的顺序调用其包中的 init() 函数
- 若是 package 存在依赖,调用顺序为最后被依赖的最早被初始化,例如:导入顺序 main –> A –> B –> C,则初始化顺序为 C –> B –> A –> main,一次执行对应的 init 方法。
常量、变量、init()、main()
在同一个文件中,常量、变量、init()、main() 依次进行初始化。it
init 顺序
一、在同一个 package 中,能够多个文件中定义 init 方法import
二、在同一个 go 文件中,能够重复定义 init 方法变量
三、在同一个 package 中,不一样文件中的 init 方法的执行按照文件名前后执行各个文件中的 init 方法循环
四、在同一个文件中的多个 init 方法,按照在代码中编写的顺序依次执行不一样的 init 方法引用
五、对于不一样的 package,若是不相互依赖的话,按照 main 包中 import 的顺序调用其包中的 init() 函数
六、若是 package 存在依赖,调用顺序为最后被依赖的最早被初始化,例如:导入顺序 main –> A –> B –> C,则初始化顺序为 C –> B –> A –> main,一次执行对应的 init 方法。
全部 init 函数都在同⼀个 goroutine 内执⾏。 全部 init 函数结束后才会执⾏ main.main 函数。