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

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

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,在执行的maininit。这是因为在编译的时候会先去检查导入的包,首先发现其他包里面的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中 包含调用即可

期待一起交流

短腿子猿

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

本文来自:简书

感谢作者:旧梦发癫

查看原文:go学习笔记-init函数执行顺序分析

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

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