我一直在收到关于指针接收器的错误,我决定谷歌这些术语的意思,我读了不同的来源和文档谈论指针接收器。例如:http://golang.org/doc/faq和http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go。
虽然,尽管他们谈论这些术语,但他们未能准确地定义它们。虽然,从上下文我认为它们之间的区别是将变量定义为*MyStruct
vs MyStruct
之类的指针。虽然,我不是100%肯定他们的差异,但我想对这些术语,特别是他们的差异(指针接收器和值接收器)有更正式或更确切的理解。如果可能的话,一些简单的示例代码显示它们在go中的区别将是非常棒的! (也许有必要真正理解这一点)
例如,令我困惑的是,术语指针和指针接收器之间有什么区别?或价值和价值接收者?接收器这个术语对这些概念有什么影响?
答案 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,因为在我的历史中很容易找到。