function - 为什么 Go 函数字段 setter 不保留该函数?

标签 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

为什么不是呢?请注意,如果我直接在 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/

相关文章:

go - 如何转换图像以上传 Spotify 个人资料图片?

html - 自动添加更多内容/字段(Wordpress)

python - Odoo - 添加自定义字段属性?

c - 有什么方法可以通过宏生成参数依赖于编译时信息的函数吗?

c++ - SFML 试图将类的引用作为参数传递给函数

go - 在 golang 中使用 psexec 时缺少标准输出

django - django独特领域

c++ - 为什么这个函数在没有指针的情况下改变列表值?

javascript - 函数调用和函数引用有什么区别?

go - 当结构包含获取csv数据的接口(interface)和范围时如何进行类型转换