program-initialization-and-execution
0.0.1 · The zero value#
当分配内存空间给一个变量时,比如通过申明变量(declaration)或者调用new函数,或者当创建一个值时,比如通过组合字面量(composite literal)或者调用make函数,如果没有显示初始化值,这个变量或者值会给定一个默认值,也就是零值。 bool类型零值为false,numeric类型为0,string类型为空串"",pointer、function、interface、slice、channel、map类型为nil。 零值初始化过程是递归的。
var i int
// 两者同等
var i int = 0
type T struct { i int; f float64; next *T }
t := new(T)
t.i == 0
t.f == 0.0
t.next == nil
// 两者同等
var t T
0.0.2 · Package initialization#
在一个包内,包级别的变量先逐步初始化,初始化顺序是按照变量声明顺序,且没有依赖未初始化的变量。
多个文件中的变量声明顺序由编译器所看到的文件顺序决定。
func init() { }
初始化所有包级变量,然后调用所有init函数,以在源中显示的顺序,可能在多个文件中,以编译器看到的文件顺序。 如果当前包有导入其他包,导入的包在此包初始化之前初始化。 如果一个包被多个包导入,这个包只会初始化一次。 包导入需要确认无循环依赖。
包级别变量初始化和init函数的调用,相继地发生在单个Goroutine,一次一个包。 init函数可能会启动其他Goroutines,其可以与初始化代码并行运行。 init函数的执行永远是线性的,上一个未结束,下一个不会开始。
0.0.3 · Program execution#
一个完整的Go程序通过链接一个不可导入的main及其所有导入的包(递归导入)而成。 main包必须申明包名为main,同时有一个main函数。
func main() { }
程序执行:初始化main包,同时调用main函数,当函数返回时,程序退出。不等待其他(非main)goroutine完成。