问题的标题几乎引自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)
}
答案 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()。
的简写