Situation:

Go包A由3.go个文件组成,我在每个文件中使用另一个包B的函数.我必须在每个文件的开头导入B包.

Question:

B实际上是初始化了3次还是只初始化了1次?

推荐答案

简短回答:初始化只执行一次.

详细答案:引用相关规范部分-Program execution:

没有导入的包是通过将初始值赋给它的所有包级变量,然后使用名称和签名调用任何包级函数来初始化的

func init()

在其来源中定义.名称为init的包范围或文件范围标识符只能声明为具有此签名的函数.即使在单个源文件中也可以定义多个这样的函数;它们以未指定的顺序执行.

在包中,根据引用顺序初始化包级变量,并确定常量值:如果A的初始化式依赖于B,则在B之后设置A.依赖分析不依赖于要初始化的项的实际值,只依赖于它们在源代码中的出现.如果A的值包含提及B,包含其初始化式提及B的值,或递归提及提及B的函数,则A依赖于B.如果这样的依赖形成一个循环,那就是错误的.如果两个项不是相互依赖的,则它们将按照它们在源代码中出现的顺序进行初始化,可能在呈现给编译器的多个文件中.因为依赖关系分析是针对每个包进行的,所以如果A的初始值设定项调用在另一个引用B的包中定义的函数,它可能会产生未指定的结果.

不能从程序中的任何位置引用init函数.特别是,不能显式调用init,也不能将指向init的指针赋给函数变量.

如果包具有导入,则在初始化包本身之前初始化导入的包.如果多个包导入一个包P,P将只初始化一次.

通过构造导入包,可以保证在初始化过程中不会有循环依赖关系.

一个完整的程序是通过将一个称为main package的未导入包与它导入的所有包进行传递链接而创建的.主包必须有包名main,并声明一个不带参数且不返回值的函数main.

func main() { … }

程序执行通过初始化主程序包然后调用函数main开始.当函数main返回时,程序退出.它不等待其他(非主)Goroutine完成.

包初始化-变量初始化和init个函数的调用-在单个Goroutine中顺序进行,一次一个包.函数init可能会启动其他Goroutine,它们可以与初始化代码同时运行.但是,初始化总是对init个函数进行排序:在前一个函数返回之前,它不会启动下一个init个函数.

Go相关问答推荐

Go编译器标志-修剪路径不完全工作

难以为多个平台添加Go Bazel构建选项

如何使用我的 struct 化日志(log)记录格式使人panic ?

如何在Golang中获取mp3文件的持续时间?

重新赋值变量时未清除动态类型-这是错误吗?

如何在出现错误时停止从通道读取?

Go:为什么我不能比较 net.Addr

如何为循环扫描的bufio scanner 设置超时?

如何在 fyne-io/fyne 中设置文本的字母间距?

Yocto 无法交叉编译 GoLang Wails 应用程序

使用 ssh 从私有 gilab 仓库导入一个 go 项目:未知修订

如何模仿联合类型

如何在 Docker 容器中使用私有存储库进行身份验证

查找、解析和验证邮箱地址

为什么 reflect.TypeOf(new(Encoder)).Elem() != reflect.TypeOf(interfaceVariable)?

合并几千万文件最快的方法是什么

在 Go 中,为什么 exec.Command() 失败但 os.StartProcess() 成功启动winget.exe?

如何获得Ent中数字列的总和

Go:如何通过 GIN-Router 从 AWS S3 将文件作为二进制流发送到浏览器?

Beego - 我需要context.Context而不是 Beego 上下文