Here’s a thing you’ve likely never thought about: What if you have a compound assignment statement, where one of the variables depends on the other in the same statement.
That’s what we’re looking at today.
Order of Evaluation
…
At package level, initialization dependencies override the left-to-right rule for individual initialization expressions, but not for operands within each expression:
var a, b, c = f() + v(), g(), sqr(u()) + v() func f() int { return c } func g() int { return a } func sqr(x int) int { return x*x } // functions u and v are independent of all other variables and functions
So first notice that calling f() returns c, and calling g() returns a. c and a, in turn, are defined in same mult-assignment statement. Such a statement would be evaluated in left-to-right order, but these initialization dependencies make that impossible.
The function calls happen in the order
u(),sqr(),v(),f(),v(), andg().
First u() is called, because it has no initialization dependencies, and it’s required to evaluate sqr(). Then sqr() is evaluated and v(), to complete the evaluation of c. This is the right-most assignment in the list, so would normally be executed first, but since c is required to evaluate f(), which is in the left-most assignment, it must happen first.
With that out of the way, we can finally execute f() and v() (again), to complete the assignment to a.
Then g() can be evaluated, to finalize the assignment to b.
Pro tip: If you ever have code like this, just rewrite it to be more obvious and less confusing:
c := sqr(u()) + v()
a := f() + v()
b := g()
Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)