鉴于这个简短的计划:
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
为什么不呢?请注意,如果我foo.doer
直接设置,输出是预期的main()
.如果我使用这种SetDoer
方法就不行.
在Go中,函数名左侧的项是接收类型.这是可以调用函数的类型.但是,接收器既可以是指针,也可以是值类型.在这种情况下,它是一个值.接收器纯粹是为了组织的目的,在封面下,它像任何其他参数一样传递给函数.您正在传递值,因此foo
传入一个副本,SetDoer
修改该值,然后设置器返回,该值超出范围,并且在调用范围内您正在使用原始值.
试试这个;
// 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.
游乐场示例; https://play.golang.org/p/ZQlvKiluu3