我试图找到 init()
函数在Go中的功能的精确解释 . 我读了Effective Go所说的但我不确定我是否完全理解它所说的内容 . 我不确定的确切句子如下:
最后意味着:在包中的所有变量声明已经评估了它们的初始值设定项之后调用init,并且只有在初始化了所有导入的包之后才会对它们进行求值 .
all the variable declarations in the package have evaluated their initializers
是什么意思?这是否意味着如果在包及其文件中声明"global"变量,init()将不会运行直到所有它都被评估,然后它将运行所有init函数,然后运行./main_file_name时运行main()?
我还阅读了Mark Summerfield的以下书:
如果一个包有一个或多个init()函数,它们会在调用主包的main()函数之前自动执行 .
根据我的理解, init()
仅在您运行打算运行main()时才相关?或主包 . 任何人都能更准确地理解 init()
随时纠正我
9 回答
mutil init函数在一个包执行顺序中:
const和变量定义文件init()函数执行
init函数按文件名asc执行命令
init func先运行然后运行main . 它用于在程序运行之前先设置一些东西,例如:
访问模板,使用所有核心运行程序,检查Goos和arch等...
是的,假设你有this:
保证
AnswerToLife()
在调用init()
之前运行,并且保证init()
在调用main()
之前运行 .请记住,始终会调用
init()
,无论是否存在main,因此如果导入具有init
函数的包,则会执行该函数 .//编辑
另外,请记住,每个包可以有多个
init()
函数,它们将按照它们在代码中显示的顺序执行(当然,在所有变量初始化之后) .//编辑2x
许多内部Go包使用
init()
初始化表等,例如https://github.com/golang/go/blob/883bc6/src/compress/bzip2/bzip2.go#L480//编辑3x
@benc在同一个包执行顺序中有多个inits:
看到这张照片 . :)
import --> const --> var --> init()
如果包导入其他包,则首先初始化导入的包 .
然后初始化当前包的常量 .
然后当前包的变量是initialiszd .
最后,调用当前包的
init()
函数 .要添加的东西(我会在评论中添加,但写这篇文章的时间我还没有足够的声誉)
在同一个包中有多个inits我还没有找到任何保证的方式来知道它们将以什么顺序运行 . 例如,我有:
config.go
和router.go
都包含init()
函数,但是当运行router.go
的函数首先运行时(这导致我的应用程序出现恐慌) .如果您处于多个文件的情况下,每个文件都有自己的
init()
函数,请注意您不能保证在另一个文件之前得到一个文件 . 在他的示例中,最好使用变量赋值作为OneToOne . 最好的部分是:此变量声明将在包中的所有init()
函数之前发生 .例如
config.go:
router.go:
无论
router.go
或config.go
中是否存在var ConfigSuccess = configureApplication()
,它都将在运行EITHERinit()
之前运行 .这是另一个例子 - https://github.com/alok87/gobyexample/blob/master/init/init.go
输出上述程序
以您为其他用户设计的框架或库为例,这些用户最终将在其代码中使用
main function
来执行他们的应用程序 . 如果用户直接导入库项目的子包,则首先将调用该子包的init
( once ) . 对于库的根包等也一样......有很多次 you may want a code block to be executed 没有
main func
,直接或不存在 .如果您作为虚构库的开发人员导入具有
init
函数的库的子包,它将首先被调用并且 once ,您没有main func
但是您需要确保一些变量或表将在其他函数调用之前初始化 .要记住并且不要担心的好事是: the init always execute once per application.
init
执行发生:在"caller"包的
init
函数之前,之前,可选地,
main func
,但是在包级变量之后,
var = [...] or cost = [...]
,When you import a package it will run all of its init functions, by order .
我名为
mime
的库和包级函数将直接使用mime
标准包来获取已在其init
函数中初始化的自定义mime类型:希望能帮助您和其他用户,如果您有更多问题,请不要犹豫再次发帖!
https://golang.org/ref/mem#tmp_4
init
将被调用到处使用它的包(无论空白导入还是导入),但只有一次 .这是一个包:
任何包(主包或任何测试包)将其导入为空白:
或使用它导入它func:
init只会记录一次
0
. 使用它的第一个包,它的init func将在包的init之前运行 . 所以:A调用B,B调用C,所有调用都有init函数,C的init将在B之前运行,B在A之前运行 .