指针接收器和值接收器在Golang中的含义是什么?

时间:2014-06-24 15:48:58

标签: pointers go

我一直在收到关于指针接收器的错误,我决定谷歌这些术语的意思,我读了不同的来源和文档谈论指针接收器。例如:http://golang.org/doc/faqhttp://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go

虽然,尽管他们谈论这些术语,但他们未能准确地定义它们。虽然,从上下文我认为它们之间的区别是将变量定义为*MyStruct vs MyStruct之类的指针。虽然,我不是100%肯定他们的差异,但我想对这些术语,特别是他们的差异(指针接收器和值接收器)有更正式或更确切的理解。如果可能的话,一些简单的示例代码显示它们在go中的区别将是非常棒的! (也许有必要真正理解这一点)

例如,令我困惑的是,术语指针和指针接收器之间有什么区别?或价值和价值接收者?接收器这个术语对这些概念有什么影响?

1 个答案:

答案 0 :(得分:5)

由于您澄清了您对术语接收器感到困惑,而不是指针/值的区别。在Go"接收器"为了接口的目的,它是指定义方法的值。您可以将接收器视为函数的第一个参数的特殊情况。

func (m MyStruct) DoStuff()

这就是所谓的"值接收器",它是在 MyStruct上定义的。这在功能上与:

相同
func DoStuff(m MyStruct)

除了:

使用"接收器"你用"。"来调用函数,就像许多OO语言一样:

 m := MyStruct{} 
 m.DoStuff() // as opposed to DoStuff(m)

类型是接收器的方法集定义了它实现的接口:

type DoesStuff interface {
    DoStuff()
}

func DoSomething(d DoesStuff) {
    d.DoStuff()
}

func main() {
    m := MyStruct{}
    DoSomething(m)
}

那么指针接收器是什么?它看起来像这样:

func (m *MyStruct) DoOtherStuff()

差异正是指针和值之间的差异。虽然发生了轻微的语义变化。 Go将自动解析和自动解除引用指针(在大多数情况下),因此m := MyStruct{}; m.DoOtherStuff()仍可正常工作,因为Go会自动为(&m).DoOtherStuff()执行操作。 (当然,你也可以自由地做m := &MyStruct{}; m.DoOtherStuff)。此外,接口是在指针上定义的,所以:

type DoesOtherStuff interface {
    DoOtherStuff()
}

func DoSomethingElse(d DoesOtherStuff) {
    d.DoOtherStuff()
}

func main() {
    m := MyStruct{}
    // DoSomethingElse(m) will fail since because the interface
    // DoesOtherStuff is defined on a pointer receiver and this is a value
    DoSomethingElse(&m)
}

如果您仍然对使用指针接收器与可变接收器的 时感到困惑,那么简短的回答是:可能是指针接收器。已经多次回答了很长的答案,但我会简单地链接here,因为在我的历史中很容易找到。