如果S包含匿名字段T,S的方法集是否包括带接收器* T的提升方法?

时间:2013-12-03 18:25:03

标签: go

问题的标题几乎引自golang specification

  

给定结构类型S和名为T的类型,提升的方法是   包含在结构的方法集中,如下所示:

     
      
  • 如果S包含匿名字段T,则S和* S的方法集都包括带有接收方T的提升方法。* S的方法集还包括带接收方* T的提升方法。
  •   

go playground显示方法inc()已升级。

package main

import (
    "fmt"
)

// just an int wrapper
type integer struct {
    i int
}

func (self *integer) inc() {
    self.i++
}

type counter struct {
    integer
}

func main() {
    c := counter{}

    c.inc()
    fmt.Println(c)
}

1 个答案:

答案 0 :(得分:7)

不会推广* T的方法。规范并没有明确允许它,因此不允许这样做。但是,这背后有一个原因。

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

来自calls section of the Go specification

  

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

来自address operator section of the Go specification

  

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

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


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

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

  

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

把两者放在一起,你有答案。计数器是可寻址的,并且& counter包含* T的方法集。因此,counter.Inc()是(& counter).Inc()。

的简写