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

新手上路,请多包涵

我试图找到关于 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 的 go book 以下内容:

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

据我了解, init() 仅在您打算运行 main() 时才相关,对吗?任何人都更准确地理解 init() 随时纠正我

原文由 Charlie Parker 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 575
2 个回答

是的,假设你有 这个

 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() is guaranteed to run before init() is called, and init() is guaranteed to run before main() is called.

请记住 init() 总是被调用,不管是否有 main ,所以如果你导入一个有 init 函数的包,它将被执行。

此外,每个包可以有多个 init() 函数;它们将按照它们在文件中出现的顺序执行(当然是在所有变量都初始化之后)。如果它们跨越多个文件,它们将按词法文件名顺序执行(正如 @benc 所指出的):

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


许多内部 Go 包使用 init() 来初始化表等,例如 https://github.com/golang/go/blob/883bc6/src/compress/bzip2/bzip2.go#L480

原文由 OneOfOne 发布,翻译遵循 CC BY-SA 4.0 许可协议

看这张照片。 :)

import --> const --> var --> init()

  1. 如果一个包导入其他包,导入的包首先被初始化。

  2. 然后初始化当前包的常量。

  3. 然后初始化当前包的变量。

  4. 最后调用当前包的 init() 函数。

一个包可以有多个 init 函数(在单个文件中或分布在多个文件中)并且它们按照它们呈现给编译器的顺序被调用。

即使从多个包中导入一个包,也只会初始化一次。

原文由 weaming 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题