鉴于这个简短的程序:
package main
import "fmt"
type Foo struct {
doer func()
}
func (f Foo) SetDoer(doer func()) {
f.doer = doer
}
func main() {
foo := Foo{func() { fmt.Println("original") }}
foo.doer()
foo.SetDoer(func() { fmt.Println("replacement") })
foo.doer()
}
输出为:
original
original
我原以为会是:
original
replacement
为什么不是呢?请注意,如果我直接在 main()
中设置 foo.doer
,输出将符合预期。如果我使用 SetDoer
方法,则不会。
最佳答案
在Go中,函数名左边的一项是接收类型。这是可以调用函数的类型。但是,接收者可以是指针或值类型。在本例中,它是一个值。接收者纯粹是为了组织的目的,在幕后,它像任何其他参数一样传递给函数。您按值传递,因此 foo
的副本被传递到 SetDoer
中,该值被修改,然后 setter 返回,该值超出范围并在调用中您正在使用原始内容的范围。
试试这个;
// make the receiver a pointer
func (f *Foo) SetDoer(doer func()) {
f.doer = doer
}
// instantiate as pointer
foo := &Foo{func() { fmt.Println("original") }}
foo.SetDoer(func() { fmt.Println("replacement") })
// now the version of doer on foo has been updated.
Playground 示例; https://play.golang.org/p/ZQlvKiluu3
关于function - 为什么 Go 函数字段 setter 不保留该函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34099860/