If one package has multiple .go files, the go tool sorts them by name before invoking the compiler, so they are initialized in lexical file name order. What if a package-level variable x in file a.go has dependencies on a package-level variable y in file b.go? Should it be user’s responsibilities to avoid such circumstances?
I’m not speaking English, sorry for misrepresentation, if any.
Within a package, package-level variable initialization proceeds stepwise, with each step selecting the variable earliest in declaration order which has no dependencies on uninitialized variables.
More precisely, a package-level variable is considered ready for initialization if it is not yet initialized and either has no initialization expression or its initialization expression has no dependencies on uninitialized variables. Initialization proceeds by repeatedly initializing the next package-level variable that is earliest in declaration order and ready for initialization, until there are no variables ready for initialization.
If any variables are still uninitialized when this process ends, those variables are part of one or more initialization cycles, and the program is not valid.
If x in a.go depends on y in b.go and y doesn’t depend on x, directly or indirectly, it’s not a cycle, it’s good. y is initialized then x is initialized.
$ cat a.go
package main
var x = 2 * y
$ cat b.go
package main
var y = 42
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println(x, y)
}
$ go run a.go b.go main.go
84 42
$
So, only variable y in b.go is initialized because x depends on it, and all the other package-level variables in b.go is left uinitialized until b.go is initialized, is that right?
For the first step through a.go then b.go, y is selected because it’s “the variable earliest in declaration order which has no dependencies on uninitialized variables.” For the second step, when y has been initialized, x is selected because it’s “the variable earliest in declaration order which has no dependencies on uninitialized variables.”