为了账号安全,请及时绑定邮箱和手机立即绑定

Go 中基类型方法指针的选择器

Go 中基类型方法指针的选择器

Go
largeQ 2023-07-17 16:30:08
很明显,下面的代码可以正常工作:package mainimport "fmt"type T struct {    a int}func (t T) M() {    fmt.Println("M method")}func main() {    var t = &T{1}    t.M() // it's interesting}但正如我从规范中看到的:对于 T 或 *T 类型的值 x(其中 T 不是指针或接口类型),xf 表示 T 中最浅深度处存在 f 的字段或方法。如果不存在恰好一个深度最浅的 f,则选择器表达式是非法的。但在示例中M不是来自*T,而是来自T。我知道其中*T包括 的方法集T,但正如我所见,规范并没有告诉我们有关 的方法集*T。我是否理解带有注释的行的规范错误或正确性是基于其他规范规则?
查看完整描述

2 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

你引用:

x.f表示最浅深度的字段或方法T

引文指的是深度深度的“定义”是:

选择器可以表示类型的f字段或方法,也可以指的嵌套嵌入字段的字段或方法。遍历到达的嵌入字段的数量称为它的深度中声明的字段或方法的深度为零。在嵌入字段in中声明的字段或方法的深度是in的深度加一。fTfTfTfTfATfA

关键是嵌入。您的结构不嵌入单一类型。所以根据定义, your的深度T.M为零。

您的t变量是类型*T(即表达式的类型&T{},它采用结构复合文字的地址:它生成一个指向用文字值初始化的唯一变量的指针)。

并引用规范:方法值:

与选择器一样,使用指针对具有值接收器的非接口方法的引用将自动取消对该指针的引用:pt.Mv相当于(*pt).Mv

t.M是对非接口方法 的引用T.M,并且由于t是指针,因此它将自动取消引用:(*t).M()

现在让我们看一个例子,其中“最浅深度”确实很重要。

type T struct{}


func (t T) M() { fmt.Println("T.M()") }


type T2 struct {

    T // Embed T

}


func (t T2) M() { fmt.Println("T2.M()") }


func main() {

    var t T = T{}

    var t2 T2 = T2{T: t}

    t2.M()

}

在main()我们调用t2.M(). 由于T2嵌入T,这可以指T2.T.Mand T2.M。但由于 的 深度T2.T.M是1, 的 深度T2.M是0,T2.M处于 中最浅的深度T2,因此t2.M将表示T2.M且 not ,因此上面的示例打印(在Go PlaygroundT2.T.M上尝试):


T2.M()


查看完整回答
反对 回复 2023-07-17
?
四季花海

TA贡献1811条经验 获得超5个赞

来自方法集:

对应指针类型*T的方法集是用接收者*T或T声明的所有方法的集合(即也包含T的方法集)。


查看完整回答
反对 回复 2023-07-17
  • 2 回答
  • 0 关注
  • 125 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信