In what order are package-level variables initialized? What does this print?
Question 20HardGo 1.22 to 1.25
package main
import "fmt"
var a = c + b
var b = f()
var c = 1
func f() int {
fmt.Println("f called, c =", c)
return 2
}
func init() { fmt.Println("init: a =", a) }
func main() { fmt.Println("main") }
Output:
f called, c = 1
init: a = 3
main
Package-level variables are initialized in dependency order, not strictly top to bottom. The compiler repeatedly picks the first variable, in declaration order, whose dependencies are all initialized.
adepends onbandc, so it isn't ready.b = f()depends onf, andf's body refers toc. The dependency analysis follows references into function bodies, sobdepends onc.cisn't initialized yet, sobisn't ready either.c = 1is ready, so it runs first.- Then
b(sofseesc = 1), thena = 3.
The rule to remember: references, including those inside functions and methods that get called, create dependencies. A dependency cycle is a compile error ("initialization cycle").
After all variables are set, the init() functions run in the order they appear, and each file's init functions run in the order the files were given to the compiler (the go tool sorts them by filename).
More on Language Fundamentals & Types
- Q18What are the rules for
recover? Why doesn'tdefer recover()stop a panic? - Q19Do deferred functions run on
os.Exit,log.Fatal,runtime.Goexitandpanic? - Q21How does initialization work across packages, and what are the rules for
init()? - Q22How do labeled
breakandcontinuework? Why does a plainbreakinsideselectnot leave the loop? - Q23What restrictions does Go place on
goto? - Q24How does
switchdiffer from C, and what does thisfallthroughexample print?