我正在阅读有关选择器的规范:https://golang.org/ref/spec#Selectors
为什么q.M0()
无效。虽然p.M0()
有效且q=p
。对我来说很奇怪。
相关的源代码:
type T0 struct {
x int
}
func (*T0) M0()
type T1 struct {
y int
}
func (T1) M1()
type T2 struct {
z int
T1
*T0
}
func (*T2) M2()
type Q *T2
var t T2 // with t.T0 != nil
var p *T2 // with p != nil and (*p).T0 != nil
var q Q = p
p.M0() // ((*p).T0).M0() M0 expects *T0 receiver
q.M0() // (*q).M0 is valid but not a field selector
答案 0 :(得分:7)
为什么
q.M0()
无效。虽然p.M0()
有效且q=p
。对我来说很奇怪。
q
初始化为var q Q = p
,但并不意味着它们是平等的。 assignment有效,因为它不违反assignability规则,但q
的类型与p
的类型不同。
q
的类型为Q
(其中type Q *T2
),p
的类型为*T2
。
在Go中,方法属于特定类型。当你这样做时:
type Q *T2
它创建一个名为Q
的新类型(*T2
是其基础类型)。新类型将有0个方法,它不会"继承"来自*T2
的任何方法,因此q.M0()
将是编译时错误:
q.M0 undefined(类型Q没有字段或方法M0)
注意:强>
你可能仍然觉得它很奇怪,因为M0()
被声明为:
func (*T0) M0()
它有*T0
个接收者,因此它属于*T0
类型,但p
的类型为*T2
,因此*T2
不应该有此M0()
1}}方法,因此p.M0()
也应无效。但是T2
是embeds *T0
的结构,因此*T0
的方法提升,它们将位于method set中} T2
。
另请参阅此相关问题:Golang: Why selector to pointers is illegal after comparison?