Thank you to everyone who responded to yesterday’s pop quiz! I got a number of responses, both by email, and on LinkedIn and Mastodon.
And the majority of responses made the exact same mistake I made, and assumed the code was invalid, because a
is referenced before it’s initialized:
var x = a
var a = 3
And while it’s true that this is an error within a function, much to my surprise, it’s actually completely valid in package scope, as we’ll see now.
Package initialization
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.
Multiple variables on the left-hand side of a variable declaration initialized by single (multi-valued) expression on the right-hand side are initialized together: If any of the variables on the left-hand side is initialized, all those variables are initialized in the same step.
var x = a var a, b = f() // a and b are initialized together, before x is initialized
For the purpose of package initialization, blank variables are treated like any other variables in declarations.
So there you have it. The answer to yesterday’s quiz is: “It depends!”
If the code is found in a function, it is invalid*, but if found in package scope, it is valid.
*Actually, one creative response I received found a way to make that code valid within a function as well:
func foo() {
var a = 1
{
var x = a
var a = 3
/* ... */
}
}
Very clever! Fifteen thousand bonus points for that response!
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)