Golang defer behavior
go
Solution
That seems coherent (see also "Defer, Panic, and Recover")
Deferred function calls are executed in Last In First Out order after the surrounding function returns.
This function prints "3210":
func b() {
for i := 0; i < 4; i++ {
defer fmt.Print(i)
}
}
The last call when the `defer` is evaluated means `i=3`, the previous to last means `i=2` and so on.
Golang spec:
Each time the "`defer`" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function body is not executed.
the `defers` will be called when func ends
yes, but their arguments are evaluated before, while the loop is running.
You have a trickier defer case in "How golang's “defer” capture closure's parameter?" when used with closure (function literal), as detailed in "Why add “`()`” after closure body in Golang?".
Problem
Effective Go states the following regarding defer: The arguments to the deferred function (which include the receiver if the function is a method) are evaluated when the defer executes, not when the call executes. Besides avoiding worries about variables changing values as the function executes, this means that a single deferred call site can defer multiple function executions. Here's a silly example. ``` for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i) } ``` Deferred functions are executed in LIFO order, so this code will cause `4 3 2 1 0` to be printed when the function returns. This example confuses me. If parameters are evaluated when the defer call is executed, then the defers in the for loop should print `5 5 5 5 5` since the defers will be called when the for loop ends, and at that time `i` would be 5. Evaluating defers at the end of the for loop will thus result in 5 for all calls. Am I missing something here?