I wrote the following golang code and ran it.
type test struct { name string } func (t test) hello() { fmt.printf("hello, %s\n", t.name) } func (t *test) hello2() { fmt.printf("pointer: %s\n", t.name) } func runt(t test) { t.hello() } func main() { mapt := []test{ {name: "a"}, {name: "b"}, {name: "c"}, } for _, t := range mapt { defer t.hello() defer t.hello2() } }
Output:
pointer: C Hello, C pointer: C Hello, B pointer: C Hello, A
My understanding is that the pointer t
will point to "c" after 3 loops, so the three 3 "c"s are used for the "hello2" output. However, delaying the "hello" function call behaves very strangely. It looks like it's retaining the location it points to. (t test)
How to affect this?
I'm curious as to what golang compiles this into. Thank you so much!
In the for loop, the parameter of the defer
statement is a closure. The closure captures the loop variable t
.
For calls using a value receiver, the closure contains a copy of t
. For calls using pointer receivers, the closure contains a pointer to t
.
Loop variables are rewritten on each iteration (this behavior will change in later versions of the language). Therefore, value receiver closures capture every value, while pointer receiver closures only capture the pointer, so at runtime they use the latest value of that pointer.
The above is the detailed content of For the same structure, Golang behaves differently in defer in for loop. For more information, please follow other related articles on the PHP Chinese website!