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

这是中的论点go1.12.3 linux/amd64。


s通过变量向包含函数的切片添加了两个闭包x。闭包是通过具有 类型的指针接收器的方法获得的T。通过变量 x 向包含函数的切片 s 添加了两个闭包。闭包是通过具有类型 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

以上两个功能,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的调用规范?

请给我一些建议。


汪汪一只猫
浏览 87回答 1
1回答

达令说

因为在糟糕的情况下,您只有一个x类型为 T 的变量,而一个变量只有一个地址,因此您的 slice s 始终包含在同一变量上工作的相同函数,当您开始调用函数时,该变量的值为 2。(好吧,你有两个不同的 T 类型变量。你重用了一个 *T 类型的变量 (x) 但你仍然有两个不同的T 具有不同的值。)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go