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

Posted

技术标签:

【中文标题】Golang:为啥指针选择器在比较后是非法的?【英文标题】:Golang: Why selector to pointers is illegal after comparison?Golang:为什么指针选择器在比较后是非法的? 【发布时间】:2017-04-09 18:37:23 【问题描述】:

我正在阅读关于选择器的规范: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

【问题讨论】:

我知道文档解释了它。但请不要投反对票。如果我问,这意味着我试图理解,但没有成功。我知道两件事:1. 这里的人喜欢对golang 问题投反对票。 2. 这里的人用 Markdown 语言解释复杂事物的能力更强。 【参考方案1】:

为什么q.M0() 无效。而p.M0() 有效且q=p。对我来说很奇怪。

qvar 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()方法,因此p.M0()也应该是无效的。但是T2是一个结构体,其中embeds*T0,所以*T0的方法被提升,它们将在T2的method set中。

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

【讨论】:

谢谢。真的很有帮助

以上是关于Golang:为啥指针选择器在比较后是非法的?的主要内容,如果未能解决你的问题,请参考以下文章

浓缩咖啡:为啥旋转器在选择后不关闭?

为啥我的 jQuery :not() 选择器在 CSS 中不起作用?

为啥我的 jQuery :not() 选择器在 CSS 中不起作用?

为啥 jQuery UI 日期选择器在 jQuery 对话框模式中不起作用?

为啥我的 Java 自定义单元格渲染器在选择行/单元格时不显示突出显示?

为啥指向未定义结构的指针有时在 C 和 C++ 中是非法的