我知道golang允许在一个包中使用多个init,甚至在一个文件中。 我想知道为什么? 例如,如果一个pkg有很多文件,我们可以写多个init然后我们可能会丢失我们应该把init放到哪里,如果我们在一个pkg中有多个init,我们也会对init命令感到困惑。 (我的意思是这更好吗?我们只能有1个init,然后我们可以有一些initXXX,然后把它们放到init中,看起来很干净。) 在代码结构视图中执行此操作的优点是什么?
答案 0 :(得分:10)
这个问题可能有点基于意见,但使用多个包init()
函数可以使您的代码更易于阅读和维护。
如果源文件很大,通常按照某种逻辑顺序排列其内容(例如类型,变量声明,方法等)。允许多个init()
函数使您可以将初始化代码放在它们应该初始化的部分附近。如果不允许这样做,你将被迫每个包使用一个init()
函数,并将所有内容放入其中,远离它们初始化所需的变量。
是的,拥有多个init()
函数可能需要关注执行顺序,但要知道使用多个init()
函数不是必需的,它只是一种可能性。并且您可以将init()
函数写入没有" side"效果,不依赖于其他init()
函数的完成。
如果这是不可避免的,你可以创建一个" master" init()
明确控制其他孩子的顺序" init()
函数。
"主人的一个例子" init()
控制其他初始化函数:
func init() {
initA()
initB()
}
func initA() {}
func initB() {}
在上面的示例中,initA()
将始终在initB()
之前运行。
规范中的相关部分:Package initialization。
答案 1 :(得分:0)
多个init()
函数的另一个用例是基于构建标记添加功能。 init()
函数可用于将钩子添加到现有包中并扩展其功能。
以下是一个精简示例,演示了基于构建标签向CLI实用程序添加更多命令的过程。
package main
import "github.com/spf13/cobra"
var (
rootCmd = &cobra.Command{Use: "foo", Short: "foo"}
)
func main() {
rootCmd.AddCommand(
&cobra.Command{Use: "CMD1", Short: "Command1"},
&cobra.Command{Use: "CMD1", Short: "Command1"},
)
rootCmd.Execute()
}
以上是该实用工具的“原始”版本。
// +build debugcommands
package main
import "github.com/spf13/cobra"
func init() {
rootCmd.AddCommand(&cobra.Command{Use: "DEBUG-CMD1", Short: "Debug command1"})
}
第二个文件的内容扩展了标准命令,并附加了在开发过程中最相关的其他命令。
使用go build -tags debugcommands
进行编译将生成带有已添加命令的二进制文件,而省略-tags
标志将生成标准版本。