dounao2829
2017-07-24 10:44
浏览 871
已采纳

golang在一个包中允许多个init的目的是什么?

I know that golang allows multiple init in one package and even in one file. I am wondering why? For example, if a pkg has many files, we could write multiple init then we could get lost in where to we should put init, and we could be also confused about the init order if we have multiple init in one pkg. (I mean is this better? we can only have 1 init, then we can have some initXXX, then put them into init, it seems quite clean.) What's the advantage of doing this in code struct view?

图片转代码服务由CSDN问答提供 功能建议

我知道golang允许在一个包甚至一个文件中进行多次初始化。 我想知道为什么吗? 例如,如果一个pkg有很多文件,我们可以编写多个init,那么我们可能会迷失应该放置init的位置,如果一个pkg中有多个init,我们也可能会对init的顺序感到困惑。 (我的意思是这样更好吗?我们只能有1个init,然后我们可以有一些initXXX,然后将它们放入init,看起来很干净。) 在代码结构视图中这样做的好处是什么? \ n

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • drygauost253590142 2017-07-24 10:54
    已采纳

    This question may be somewhat opinion based, but using multiple package init() functions can make your code easier to read and maintain.

    If your source files are large, usually you arrange their content (e.g. types, variable declarations, methods etc.) in some logical order. Allowance of multiple init() functions give you the possibility to put initialization code near to the parts they ought to initialize. If this would not be allowed, you would be forced to use a single init() function per package, and put everything in it, far from the variables they need to initialize.

    Yes, having multiple init() functions may require some care regarding the execution order, but know that using multiple init() functions is not a requirement, it's just a possibility. And you can write init() functions to not have "side" effects, to not rely on the completion of other init() functions.

    If that is unavoidable, you can create one "master" init() which explicitly controls the order of other, "child" init() functions.

    An example of a "master" init() controlling other initialization functions:

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

    In the above example, initA() will always run before initB().

    Relevant section from spec: Package initialization.

    Also see related question: What does lexical file name order mean?

    点赞 评论
  • dongtangxi1584 2019-07-30 13:34

    Another use case for multiple init() functions is adding functionality based on build tags. The init() function can be used to add hooks into the existing package and extend its functionality.

    The following is a condensed example demonstrating the addition of more commands to a CLI utility based on build tags.

    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()
    }
    

    The above is the "vanilla" version of the utility.

    // +build debugcommands
    
    package main
    
    import "github.com/spf13/cobra"
    
    func init() {
        rootCmd.AddCommand(&cobra.Command{Use: "DEBUG-CMD1", Short: "Debug command1"})
    }
    

    The contents of the second file extends the standard command with additional commands that are mostly relevant during development.

    Compiling using go build -tags debugcommands will produce a binary with the added commands, while omitting the -tags flag will produce a standard version.

    点赞 评论

相关推荐 更多相似问题