我知道Golang允许在一个包甚至一个文件中包含多个init. 我想知道为什么? 例如,如果一个pkg有很多文件,我们可能会写多个init,那么我们可能会迷路,不知道应该把init放在哪里,如果我们在一个pkg中有多个init,我们也可能会混淆init的顺序.(我的意思是这是不是更好?我们只能有一个init,然后我们可以有一些initXXX,然后把它们放到init中,看起来很干净.) 在代码 struct 视图中执行此操作有什么好处?

推荐答案

这个问题可能有些基于意见,但是使用多个Package init()函数可以使您的代码更容易阅读和维护.

如果源文件很大,通常会按照某种逻辑顺序排列它们的内容(例如类型、变量声明、方法等).允许使用多个init()函数,可以将初始化代码放在应该初始化的部分附近.如果这是不允许的,您将被迫在每个包中使用一个init()函数,并将所有内容都放在其中,远离需要初始化的变量.

是的,拥有多个init()函数可能需要注意执行顺序,但要知道使用多个init()函数并不是必需的,它只是一种可能性.而且您可以编写init()个函数来不产生"副作用",不依赖于其他init()个函数的完成.

如果这是不可避免的,您可以创建一个"主"init(),它显式地控制其他"子"init()函数的顺序.

"主"init()控制其他初始化功能的示例:

func init() {
    initA()
    initB()
}

func initA() {}
func initB() {}

在上面的示例中,initA()将始终在initB()之前运行.

规格:Package initialization的相关章节.

另见相关问题:What does lexical file name order mean?

Go相关问答推荐

如何创建两个连接的io.ReadWriteClosers以用于测试目的

更改位置级别和时间戳零点Golang

理解Golang中的IOTA和常量

Python样式生成器实现为通道:过早读取

调用库和直接操作效率有区别吗?

Go-如何在递归函数中关闭通道

用 fork 替换 Go 依赖:...用于两个不同的模块路径

使用 OpenTelemetry 统一不同服务的范围

在VSCode中如何使用特定的文件名提供编译命令

这是实现超时的常见方法,为什么 time.After 不起作用

为什么docall在singleflight中使用go panic?

errors.Wrap 和 errors.WithMessage 有什么区别

Golang:如何判断通过缓冲通道进行通信时生产者或消费者是否较慢?

数据流中的无根单元错误,从 Golang 中的 PubSub 到 Bigquery

来自洪流公告的奇怪同行字段

无法建立连接,因为目标机器主动拒绝它 Golang

如何在Go中替换符号并使下一个字母大写

从 Go struct 中提取标签作为 reflect.Value

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

如何断言类型是指向golang中接口的指针