一尘不染

init() 函数什么时候运行?

go

我试图找到该init()函数在 Go 中的作用的精确解释。我读了Effective Go所说的,但我不确定我是否完全理解它所说的。我不确定的确切句子如下:

finally 的意思是 finally:在包中的所有变量声明都评估了它们的初始值设定项之后调用 init,并且只有在所有导入的包都已初始化之后才评估它们。

什么all the variable declarations in the package have evaluated their initializers意思?这是否意味着如果您在包及其文件中声明“全局”变量,init() 将不会运行,直到所有它都被评估,然后它将运行所有 init 函数,然后在运行 ./main_file_name 时运行 main()?

我还阅读了 Mark Summerfield 的围棋书:

如果一个包有一个或多个 init() 函数,它们会在主包的 main() 函数被调用之前自动执行。

在我的理解中,init()只有当您打算运行 main() 时才相关,对吗?或主包。任何人都更准确地理解init()随时纠正我


阅读 326

收藏
2021-10-26

共1个答案

一尘不染

是的,假设你有这个:

var WhatIsThe = AnswerToLife()

func AnswerToLife() int { // 1
    return 42
}

func init() { // 2
    WhatIsThe = 0
}

func main() { // 3
    if WhatIsThe == 0 {
        fmt.Println("It's all a lie.")
    }
}

AnswerToLife()保证在init()被调用之前运行,并且init()保证在main()被调用之前运行。

请记住init(),无论是否存在 main ,它始终被调用,因此如果您导入具有init函数的包,它将被执行。

此外,init()每个包可以有多个功能;它们将按照它们在文件中显示的顺序执行(当然是在所有变量初始化之后)。如果它们跨越多个文件,它们将按词法文件名顺序执行:

似乎init()函数是按词法文件名顺序执行的。Go 规范说“鼓励构建系统以词法文件名顺序将属于同一包的多个文件呈现给编译器”。似乎是这样go build工作的。

2021-10-26