In the godoc(https://blog.golang.org/defer-panic-and-recover), there is an example:
- Deferred functions may read and assign to the returning function's named return values.
In this example, a deferred function increments the return value i after the surrounding function returns. Thus, this function returns 2:
func c() (i int) {
defer func() { i++ }()
return i
}
I also wrote a small progam:
package main
import "fmt"
func b() int {
i := 0
for ; i < 4; i++ {
defer func() {fmt.Println(i); i++} ()
}
return i
}
func main() {
fmt.Println("result = ", b())
}
the output is:
4
5
6
7
result = 4
So I am confused, why does the second example not output 8
?
Note the part that says "may read and assign to the returning function's named return values."
This means that:
func b() int {
var i int
defer func() { fmt.Println(i); i++ }()
return i
}
will say 0
and result = 0
, while:
func b() (i int) {
defer func() { fmt.Println(i); i++ }()
return i
}
will say 0
and result = 1
.
It might help to imagine that the return i
in my first example assigns the i
value to a hidden return variable (because it's not named), then goes on to execute the defer
statements (which only modify the local variable i
), while in the second example we assign directly to the return variable (because it's named) and so the defer
statement is able to change it.
Basically your program could be interpreted like this:
package main
import "fmt"
func b() (hiddenVariable int) {
i := 0
for ; i < 4; i++ {
defer func() { fmt.Println(i); i++ }()
}
hiddenVariable = i; return // implicit meaning of return i
}
func main() {
fmt.Println("result = ", b())
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With