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

Ami*_*ein 6 methods types pointers go

我正在阅读关于选择器的规范: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
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 7

为什么q.M0()无效.虽然p.M0()是有效的q=p.对我来说很奇怪.

q被初始化var q Q = p,但并不意味着它们是平等的.该分配是有效的,因为它不违反转让性规则,但键入q比类型的不同p.

类型qQ(where type Q *T2),类型p*T2.

在Go中,方法属于特定类型.当你这样做:

type Q *T2
Run Code Online (Sandbox Code Playgroud)

它创建一个名为Q(*T2作为其基础类型)的新类型.新类型将有0个方法,它不会"继承"任何方法*T2,因此q.M0()将是编译时错误:

q.M0 undefined(类型Q没有字段或方法M0)

注意:

您可能仍然认为它很奇怪,因为M0()声明如下:

func (*T0) M0()
Run Code Online (Sandbox Code Playgroud)

它有*T0接收器所以它属于类型*T0,但类型p*T2,所以*T2不应该有这种M0()方法,因此也p.M0()应该是无效的.不过T2是一个结构嵌入 *T0等方法*T0进行推广,他们将在方法设置T2.

另请参阅此相关问题:Golang:为什么选择指针在比较后是非法的?