我正在读关于选择器的规范:
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
Why
q.M0()
is invalid. Whilep.M0()
is valid andq=p
. Very strange for me.
q初始化为var q Q = p,但并不意味着它们是相等的. assignment是有效的,因为它不违反assignability规则,但q的类型与p的类型不同.
q的类型是Q(其中类型Q * T2),并且p的类型是* T2.
在Go中,方法属于特定类型.当你这样做:
type Q *T2
它创建一个名为Q的新类型(* T2是其基础类型).新类型将有0个方法,它不会从* T2“继承”任何方法,因此q.M0()将是编译时错误:
q.M0 undefined (type Q has no field or method M0)
注意:
您可能仍然认为它很奇怪,因为M0()声明如下:
func (*T0) M0()
它有* T0接收器所以它属于* T0类型,但是p的类型是* T2,所以* T2不应该有这个M0()方法,因此p.M0()也应该是无效的.但T2是embeds * T0的结构,因此* T0的方法被提升,它们将在T2的method set中.
另请参阅此相关问题:Golang: Why selector to pointers is illegal after comparison?