`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)
有疑问加站长微信联系(非本文作者))