Today’s section of the spec is a bit dense and technical. But don’t worry, it makes a lot of sense once we get to the end.
Package initialization
…
Dependency analysis does not rely on the actual values of the variables, only on lexical references to them in the source, analyzed transitively. For instance, if a variable
x
’s initialization expression refers to a function whose body refers to variabley
thenx
depends ony
. Specifically:
- A reference to a variable or function is an identifier denoting that variable or function.
- A reference to a method
m
is a method value or method expression of the formt.m
, where the (static) type oft
is not an interface type, and the methodm
is in the method set oft
. It is immaterial whether the resulting function valuet.m
is invoked.- A variable, function, or method
x
depends on a variabley
ifx
’s initialization expression or body (for functions and methods) contains a reference toy
or to a function or method that depends ony
.For example, given the declarations
var ( a = c + b // == 9 b = f() // == 4 c = f() // == 5 d = 3 // == 5 after initialization has finished ) func f() int { d++ return d }
the initialization order is
d
,b
,c
,a
.
All of this to say that what would make intutive sense holds: If, for example, a package-level variable initialization calls a function, which in turn references a package-level variable,then the dependency on that underlying package variable follows through to the other package variable. Phewh. No wonder the above section is so verbose and technical. I can’t even say it a concise way, other than: Dependencies at this level work as one would expect.
One last point in this section:
… Note that the order of subexpressions in initialization expressions is irrelevant:
a = c + b
anda = b + c
result in the same initialization order in this example.
That is to say that the initialization order is determined by the order in which the dependant variables are declared in the source, not on the order in which they’re referenced. Because b
is mentioned one line before c
, b
gets initialized beofre c
, regardless of the order in which they’re mentioned as subexpressions in the declaration of a
.
Whewh.
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)