In deferred functions you have the opportunity to modify the values of the result parameters.
When deferred functions are called, values specified in the return
statement are already set.
If there are multiple deferred functions, they are executed in LIFO order (last in, first out).
In your second example fmt.Println()
is executed first, then the other, anonymous function.
But what you need to know that when the defer
statement is executed, the arguments to the deferred function are evaluated immediately, not when the deferred function will be run (later, before returning).
Spec: Defer statements:
Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred.
So this line:
defer fmt.Println("our i is", i)
Will always mean to call fmt.Println()
with i = 0
argument:
fmt.Println("our i is", 0)
Because when this line runs, i
has a value of 0
.
So in your 2nd example fmt.Println()
prints 0
, then runs the other deferred function which sets i
to 1
and this is what is returned.
Your first example just prints something (i = 0
), but the deferred functions in the first example do not modify the value of i
so 45
will be returned (and printed by the fmt.Println()
function from the main()
).
Please see the following questions/answer for more on the topic:
Defer usage clarification
How to return a value in a Go function that panics?