繁体   English   中英

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

[英]Why don't closures called from non-pointer values ​be added to slices correctly?

这是go1.12.3 linux/amd64的参数。

通过变量x向包含函数的slice s添加了两个闭包。 通过使用类型为T的指针接收器的方法获得闭包。 通过变量x向包含函数的slice 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()可以正常工作。 好的s[0]()执行T{1}.f()() ,而s s[1]()执行T{2}.f()() 但是, bad()运行s[0]()s[1]()运行T{2}.f()() 即使我将元素添加到切片时也没有覆盖它!

我不知道是什么原因导致了这种现象。 不变量x具有类型的值T而不是指针类型的值T 还是我不知道append的调用规范?

请给我一些建议。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM