# 6.1 简介

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

1. 依赖包的初始化逻辑 如果当前包依赖了其它的包，那么这些包的初始化逻辑需要首先完成，也可以看着是本包初始化任务的一部分
2. &#x20;全局变量的赋值语句 全局变量、全局常量的赋值语句也是初始化逻辑的一部分，但常量的初始化工作在类型检查时已经完成，而变量的初始化则稍微复杂一些，例如如下代码：

   ```
   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` 的初始化工作可以在编译时完成，以提升程序运行时的性能。

   &#x20;由此可见，对于全局变量的赋值语句，编译器需要确定其初始化时间（编译时或运行时）、依赖关系以及初始化的顺序。
3. `init` 函数 由 `init` 函数定义包的初始化逻辑会在包加载时自动执行，并且一个包内可以申明任意多个 `init` 函数，其执行顺序与文件中的申明顺序一致

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