Go中函数的执行次序 | 青训营笔记

81 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记

在项目开发过程中参考别人的代码时,发现main中除了那些常规的代码外,多了一个Init函数,字面意思就是初始化,这里的作用是对repository包中连接数据库进行了初始化,我的直觉是main函数应该作为函数的入口,最先被执行,那么初始化这个函数是在什么时候执行的呢?

func Init() error {
	if err := repository.Init(); err != nil {
		return err
	}
	return nil
}

在一通百度之后了解到,我的直觉是错的,原来Go程序的main包中如果有init函数,那么它是在main函数之前被调用的,并且我们不用手动的去调用它,否则会报错。

func init() {
	println("初始化。。。")
}
func main() {
	println("开始执行程序。。")
}
//执行结果
初始化。。。
开始执行程序。。
func init() {
	println("初始化。。。")
}
func main() {
	init()
	println("开始执行程序。。")
}
//执行结果
# command-line-arguments
.\main.go:7:2: undefined: init

如果main包依赖其他包,并且被依赖的包中也有init函数,那么会最先执行被依赖的包中的init函数。

package main
import(
    "dependency/pkg1"
    "dependency/pkg2"
)
func init(){
	println("main包的初始化...")
}
func main(){
	pkg1.Pkg1()
	pkg2.Pkg2()
	println("执行main程序")
}
//执行结果
pkg1初始化。。。
pkg2初始化。。。
main包的初始化...
执行pkg1
执行pkg2
执行main程序

如果依赖当中还存在依赖,那么就先执行最深的那个依赖。

所以Go包的执行次序是:

  1. 依赖包按深度优先的次序初始化;
  2. 在每个包内,按照“常量->变量->init函数”的顺序进行初始化;
  3. 包内如果有多个init函数则按出现的次序依次调用;

init函数的常用用途:

  1. 重置包级变量值。
  2. 是实现对包级变量的复杂初始化。
  3. 在init函数中实现注册模式。

函数十分适合做一些包级数据初始化工作以及包级数据初始状态的检查工作,我们也通过实例讲解了 init 函数

参考文章:time.geekbang.org/column/arti…