initinitinitinit

1. 不唯一性

init

运行结果:

init

2. 生命周期

init
initinit
api

API 对应的初始化部分都可以单独地写在每个源文件中, 引用这个 package 的开发者并不需要显示地调用初始化函数就能完成整个 package 的初始化.

init
Package initialization is done only once even if package is imported many times.

这对很多需要维护全局唯一的一些特性非常有用, 例如在流行的日志工具的实现中, 为了提升获取时间的性能, logrus 在初始化的时候获取了系统的基准时间, 而这个时间需要全局唯一, 并且只需要获取一次. 代码如下:

3. 没有输入输出的参数

init
initinit
func init must have no arguments and no return values.
init

4. 运行顺序

initinit

第一条没有什么疑问, 对于第二条, 可以简单地参考字符串比较, 例如:

  • a.go > b.go
  • a1.go > a2.go

5. 用作 side effect

标准库中的 MySQL Driver 就是通过导入一个匿名的 package 来实现 side effect. 例如:

在上面的代码中, 我们导入了 MySQL 的 Driver, 却没有显示地使用它, 那这行导入实际上发生了什么呢, 如果我们去看 这个 package 的实现, 就会发现:

init

6. Test 文件中

同一个 package 中, test 文件中的 `init` 函数和非 test 文件中的互不相干. 这样设计也是为了 test 能够足够独立和灵活.


init
initinitinitinitinitmysql.go