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

如果 S 包含匿名字段 T,那么 S 的方法集是否包含接收者 *T 的提升方法?

如果 S 包含匿名字段 T,那么 S 的方法集是否包含接收者 *T 的提升方法?

Go
呼唤远方 2021-07-08 10:01:56
问题的标题几乎引用自golang 规范:给定一个结构类型 S 和一个名为 T 的类型,提升的方法包含在结构的方法集中,如下所示:如果 S 包含匿名字段 T,则 S 和 *S 的方法集都包含接收者 T 的提升方法。 *S 的方法集还包括接收者 *T 的提升方法。这是一个go Playground展示了该方法inc()的推广。package mainimport (    "fmt")// just an int wrappertype integer struct {    i int}func (self *integer) inc() {    self.i++}type counter struct {    integer}func main() {    c := counter{}    c.inc()    fmt.Println(c)}
查看完整描述

1 回答

?
犯罪嫌疑人X

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

否 *T 的方法不会被提升。规范没有明确允许它,所以它是不允许的。然而,这背后是有原因的。


有时您可能会在 T 上调用 *T 方法。但是,会采用隐式引用。*T 的方法不被视为 T 的方法集的一部分。


从Go 规范的调用部分:


如果 x 是可寻址的并且 &x 的方法集包含 m,则 xm() 是 (&x).m() 的简写


从Go 规范的地址运算符部分:


对于 T 类型的操作数 x,地址操作 &x 生成一个类型为 *T 的指针,指向 x。操作数必须是可寻址的,即变量、指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或可寻址数组的数组索引操作。作为可寻址性要求的一个例外,x 也可以是(可能带括号的)复合文字。


如果 S 包含 *T,您甚至不需要获取它的地址以便可以调用方法。如果 *S 包含 T,则您知道 T 是可寻址的,因为 T 是指针间接结构的字段选择器。对于包含 T 的 S,无法保证这一点。


更新:为什么该代码有效?


请记住,*S 包含*T 的方法集。另外,正如我之前引用的:


如果 x 是可寻址的并且 &x 的方法集包含 m,则 xm() 是 (&x).m() 的简写


把两者放在一起,你就有了答案。Counter 是可寻址的,&counter 包含 *T 的方法集。因此,counter.Inc() 是 (&counter).Inc() 的简写。


查看完整回答
反对 回复 2021-07-12
  • 1 回答
  • 0 关注
  • 211 浏览
慕课专栏
更多

添加回答

举报

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