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)