duanputian5341
duanputian5341
2019-04-12 19:48
浏览 69
已采纳

关于Go语言的初始化(执行)顺序的问题

I am a newbie to Go. I am stuck in the initialization sequence when several go files are run, including packages, variables and the init function.

As far as I know, there are several rules:

  1. Imported packages and init functions are supposed to be called according to their sequences of appearance.

  2. If file A imports file B while file B imports file C, the initialization sequence will be C->B->A.

  3. Dependencies are always executed first.

  4. The package main is always executed at last.

There is an example that I am confused about (I was told the initialization sequence is represented by that from small numbers to big numbers, like 1.1 is executed before 1.2, 1.2 is executed before 2.1 etc.)

// p1.go

package p1

import "fmt"         //1.1

var x float32 = 1.2   //1.2

func init()  {        //1.3

       fmt.Printf("p1 package, x:%f
", x)    //1.4
}

func Donothing() {

       fmt.Println("do nothing.
")
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// a.go

package main

import "fmt"

var WhatIsThe1 = AnswerToLife(2.1) //2.1
var WhatIsThe2 = AnswerToLife(2.2) //2.2
var WhatIsThe3 = AnswerToLife(2.3) //2.3

func init() { //3.1


       fmt.Printf("init WhatIsThe in a.go `s init 3.1: %d
", 2)

}

func init() { //3.2


       fmt.Printf("init WhatIsThe in a.go`s init 3.2: %d
", 3)

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// testinit.go

package main

import "p1" //1
import "fmt"

var WhatIsThe4 = AnswerToLife(2.4) //2.4
var WhatIsThe5 = AnswerToLife(2.5) //2.5
var WhatIsThe6 = AnswerToLife(2.6) //2.6

func AnswerToLife(index float32) float32 {

       fmt.Printf("init package level variable, WhatIsThe: %f
", 
index)
       return index
}

func init() { //3.3

       fmt.Printf("init WhatIsThe in testinit.go`s init3.3: %d
", 0)

}

func init() { //3.4

       fmt.Printf("init WhatIsThe in testinit.go`s init3.4: %d
", 1)

}

func main() { //4

       p1.Donothing() //5
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// z.go

package main

import "fmt"

var WhatIsThe7 = AnswerToLife(2.7) //2.7
var WhatIsThe8 = AnswerToLife(2.8) //2.8
var WhatIsThe9 = AnswerToLife(2.9) //2.9

func init() { //3.5


       fmt.Printf("init WhatIsThe in z.go`s init 3.5: %d
", 4)

}

func init() { //3.6


       fmt.Printf("init WhatIsThe in z.go`s init 3.6: %d
", 5)

}

I am confused about those things:

  1. When a file is declaring the package main, is that okay for it to lack the main function?

  2. If there are multiple package main (s), what are the relations of all of them?

  3. As I know from other languages like Python, Javascript etc, there should be one "main file". How's the Go language?

  4. What is the initialization sequence of all package main (s)?

  5. I am confused about the sequences 2.1 ~ 2.9, why are they executed sequentially instead of executing those init functions in files a.go, testinit.go and z.go?

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

1条回答 默认 最新

  • duanlinma5885
    duanlinma5885 2019-04-12 20:04
    已采纳

    The specification says:

    A complete program is created by linking a single, unimported package called the main package with all the packages it imports, transitively. The main package must have package name main and declare a function main that takes no arguments and returns no value.

    func main() { … }
    

    Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

    Notice that there is a distinction between the main package and packages with the name main.

    1. The main package must have a main function in one if the package files. Otherwise, a file in a package named main does not need to have a main function.

    2. Program execution starts with the main package as defined above. Other packages named main have no special status.

    3. There can be multiple main packages. Only one package will meet the requirements for the main package.

    4. The package initialization order depends on the import relationship between packages. The name of any package does not play any role in determining the initialization order.

    点赞 评论

相关推荐