This is the argument in go1.12.3 linux/amd64
.
Added two closures to the slice s
containing the function through the variable x
.
The closure is obtained by a method with a pointer receiver of type T
.
Added two closures to the slice s containing the function through the variable x.
The closure is obtained by a method with a pointer receiver of type T.
package main
import "fmt"
type T struct {
X int
}
func (t *T) f() func() {
return func() { fmt.Println(t.X) }
}
func good() {
s := []func(){}
x := &T{1}
s = append(s, x.f())
x = &T{2}
s = append(s, x.f())
s[0]() // => 1
s[1]() // => 2
}
func bad() {
s := []func(){}
x := T{1}
s = append(s, (&x).f()) // Even if it rewrites to append(s, x.f()), the result is the same.
x = T{2}
s = append(s, (&x).f())
s[0]() // => 2 WHY!?
s[1]() // => 2
}
func main() {
good()
bad()
}
https://play.golang.org/p/j-818FZELQb
Of the above two functions, good()
works as expected.
In good s[0]()
executes T{1}.f()()
, and s s[1]()
executes T{2}.f()()
.
However, bad()
runs s[0]()
and s[1]()
run T{2}.f()()
.
Even though I added the element to the slice without overwriting it!
I have no idea what caused this behavior.
Didn't the variable x
have a value of type T
instead of a pointer to a value of type T
?
Or do I not know the call specification of append?
Please give me some advice.