相同库中的包的初始化顺序

相同包

  • 按go文件字典序,先执行不同go文件中的全局变量
  • 按go文件字典序,再执行不同go文件中的init()
  • 遵循字典序初始化顺序
  • 遵循依赖包优先初始化原则,优先于字典序原则

不同包

  • go文件依赖于不同包的go文件
      • 以包为单位初始化,先初始化依赖的包,包括依赖包下不依赖的go文件
      • 以包为单位初始化,按go文件字典序初始化包
  • 遵循字典序初始化顺序
    • 同路径前缀的父子包,优先加载父包
      • 不同路径路径的包,遵循字典序顺序初始化包
      • 遵循依赖包优先初始化原则,优先于字典序原则

其他

  • 同一个物理磁盘目录下只能有1个包名
  • 没有import的包也即没有被依赖的包,不会执行该包下的init()方法
  • import关键字后的包按字典序排序的顺序初始化包
  • 如何判断是否go文件依赖其他go文件?
    在import中存在的包,若import的包中的方法未被引用,则编译器不通过。即使引用的import的方法未在程序运行中调用只要在import中出现,即视为包有依赖关系
  • 父子目录的包加载顺序
 import (
    "p1"
    "p1/p3"
    "p2"
)

以上代码初始化顺序为: p1 -> p1/p3 -> p2

如果有包路径为 p1 ,p1/p3 ,p2

 import (
    "p1"
    "p2"
)

以上代码初始化顺序为: p1 -> p2, p1/p3不会被初始化

  • 如果目录名和包名不同,则import包时需要重命名包名

p2中的代码g2.go片段如下

 import (
        pnew "p1/p3"
)

p3包中的代码g3.go片段如下

package pnew

以上代码 p1/p3为物理磁盘目录路径,pnew为包名
- "_"下划线修饰的包只会初始化该包的init()方法

 import (
    _ "p1"
)

"_"下划线修饰的该包的其他方法不可被调用,除非再导入该包的不带下划线的包,如下

 import (
        _ "p1"
        "p1"
)

不同库中的包的初始化顺序

  • 标准库中的包 -> 项目内包 -> 第三方包
  • 遵循依赖包优先初始化原则,优先于字典序原则