Golang:为什么选择指针在比较后是非法的?

时间:2016-11-25 11:10:38

标签: pointers go methods types

我正在阅读有关选择器的规范:https://golang.org/ref/spec#Selectors

enter image description here

为什么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

1 个答案:

答案 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()也应无效。但是T2embeds *T0的结构,因此*T0的方法提升,它们将位于method set中} T2

另请参阅此相关问题:Golang: Why selector to pointers is illegal after comparison?