go学习笔记-init函数执行顺序分析

rundaisc · · 1416 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

`golang`中有个神奇的函数`init`,该函数会在所有程序执行开始前被调用,每个包可以包含多个`init`函数,所有被编辑器识别到的`init`函数都会在`main`函数执行前被调用。通常被用来注册一个程序需要使用的依赖,如`mysql`注册,配置文件加载等。 ###### 在main包的使用 ``` package main import "fmt" func main() { fmt.Println("这里是mian") } func init() { fmt.Println("这里是Init1") } func init() { fmt.Println("这里是Init2") } //输出结果 这里是Init1 这里是Init2 这里是main ``` 一个很简单的示例,可以看到`init`函数是在main函数执行之前被执行的,并且一个包可以有多个`init`函数 ###### 在其他包中使用 - main包 ``` package main import ( "fmt" "test/services" ) func main() { fmt.Println("这里是main") services.Run() } func init() { fmt.Println("这里是main init") } ``` - services包 ``` package services import "fmt" func Run() { fmt.Println("这里是 services run") } func init() { fmt.Println("这里是 services里面的init") } ``` - 结果 ``` 这里是 services里面的init 这里是main init 这里是main 这里是 services run ``` 可以看到这里先执行了`services`包里面的`init`,在执行的`main` 的`init`。这是因为在编译的时候会先去检查导入的包,首先发现其他包里面的`init`,然后才会到`main`包里面的init。那如果`services`里面又包含了其他的包呢?其他包里面又在不同的文件中有不的`init`呢?下面我们一起来看看到底`init`的顺序是怎么样的。 ###### 多个包嵌套 在上面的基础上增加`third`包 - 目录结构 ``` ---services -----service.go ---third -----third_a.go -----third_b.go ---main.go ``` - third_a.go ``` package third import "fmt" func TestA() { } func init() { fmt.Println("这里是 third init a") } ``` - third_b.go ``` package third import "fmt" func TestB() { } func init() { fmt.Println("这里是 third init b") } ``` - serice.go ``` package services import ( "fmt" "test/third" ) func Run() { fmt.Println("这里是 services run") third.TestB() // 先调用 testB third.TestA() // 在调用 testA } func init() { fmt.Println("这里是 services里面的init") } ``` - 结果 ``` 这里是 third init a 这里是 third init b 这里是 services里面的init 这里是 main init 这里是 main 这里是 services run ``` 可以看到这里先执行了 `third_a`中的`init`,再执行了`third_b`中的`init`,而不是按照我们函数的调用顺序来执行的,那么是按照文件的排序来定的?我觉得应该是这样的,官方只是说按源文件的顺序执行,具体是否是这样只有靠实际实践来看,目前来看是这样的顺序。其实我们大可不必纠结太多的顺序问题。 **我们只需要知道,每个包中可以有多个`init`函数,而其他包的`init`是在main包的`init`调用之前被执行,`main`函数最后执行即可,如果非要有依赖的顺序关系,那么可以在`init`中 包含调用即可** #### 期待一起交流 ![qrcode_for_gh_60813539dc23_258.jpg](https://static.studygolang.com/191229/a7469c06c43accc3f19ded734b20d55d.jpg)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1416 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传