6.1 简介

我们知道 Go 语言运行时,首先会自动对所加载的包进行初始化,按照执行顺序,一个包的初始化任务可以分为如下三类:

  1. 依赖包的初始化逻辑 如果当前包依赖了其它的包,那么这些包的初始化逻辑需要首先完成,也可以看着是本包初始化任务的一部分

  2. 全局变量的赋值语句 全局变量、全局常量的赋值语句也是初始化逻辑的一部分,但常量的初始化工作在类型检查时已经完成,而变量的初始化则稍微复杂一些,例如如下代码:

    var nameAlias string = name + "!"
    var name string = func() string {
        return "Golang"
    }()
    
    const version = "1.2"
    
    var versionAlias string = version

    变量 nameAlias 依赖于 name ,因此其初始化顺序应该在 name 之后,而 name 的初始化需要执行一个函数,这需要在程序运行时才能完成;再看 versionAlias, 其初始化逻辑只是简单地拷贝常量 version 的值,而后者在编译时便可以确定,所以看起来 versionAlias 的初始化工作可以在编译时完成,以提升程序运行时的性能。

    由此可见,对于全局变量的赋值语句,编译器需要确定其初始化时间(编译时或运行时)、依赖关系以及初始化的顺序。

  3. init 函数 由 init 函数定义包的初始化逻辑会在包加载时自动执行,并且一个包内可以申明任意多个 init 函数,其执行顺序与文件中的申明顺序一致

编译器会将以上三类初始化逻辑合并,并创建一个可执行的初始化任务,以便程序执行时调用。

最后更新于