Go

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.

  1. a depends on b and c, so it isn't ready.
  2. b = f() depends on f, and f's body refers to c. The dependency analysis follows references into function bodies, so b depends on c. c isn't initialized yet, so b isn't ready either.
  3. c = 1 is ready, so it runs first.
  4. Then b (so f sees c = 1), then a = 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

All 39 Language Fundamentals & Types questions