为了账号安全,请及时绑定邮箱和手机立即绑定

为什么从非指针值调用的闭包不能正确添加到切片中?

为什么从非指针值调用的闭包不能正确添加到切片中?

Go
汪汪一只猫 2023-06-19 15:35:49
这是中的论点go1.12.3 linux/amd64。s通过变量向包含函数的切片添加了两个闭包x。闭包是通过具有 类型的指针接收器的方法获得的T。通过变量 x 向包含函数的切片 s 添加了两个闭包。闭包是通过具有类型 T 的指针接收器的方法获得的。package mainimport "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以上两个功能,good()按预期工作。在 good s[0]()executesT{1}.f()()和 s s[1]()executes中T{2}.f()()。但是,bad()运行s[0]()并s[1]()运行T{2}.f()()。即使我将元素添加到切片中而没有覆盖它!我不知道是什么导致了这种行为。变量x的值不是 typeT而不是指向 type 值的指针吗T?还是不知道append的调用规范?请给我一些建议。
查看完整描述

1 回答

?
达令说

TA贡献1821条经验 获得超6个赞

因为在糟糕的情况下,您只有一个x类型为 T 的变量,而一个变量只有一个地址,因此您的 slice s 始终包含在同一变量上工作的相同函数,当您开始调用函数时,该变量的值为 2。

(好吧,你有两个不同的 T 类型变量。你重用了一个 *T 类型的变量 (x) 但你仍然有两个不同的T 具有不同的值。)


查看完整回答
反对 回复 2023-06-19
  • 1 回答
  • 0 关注
  • 77 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信