为什么Go函数字段设置器不保留功能?

时间:2015-12-05 00:43:01

标签: function go field accessor

鉴于这个简短的计划:

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方法,那就不行了。

1 个答案:

答案 0 :(得分:5)

在Go中,函数名左侧的项是接收类型。这是可以调用函数的类型。但是,接收器既可以是指针,也可以是值类型。在这种情况下,它是一个值。接收器纯粹是为了组织的目的,在封面下,它像任何其他参数一样传递给函数。您按值传递,因此将foo的副本传递到SetDoer,修改该值,然后设置器返回,该值超出范围,并且在调用范围内您可以&#39 ;重新使用原文。

试试这个;

// 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