Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如果S包含匿名字段T,则S的方法集是否包含receiver*T的提升方法?_Go - Fatal编程技术网

Go 如果S包含匿名字段T,则S的方法集是否包含receiver*T的提升方法?

Go 如果S包含匿名字段T,则S的方法集是否包含receiver*T的提升方法?,go,Go,问题的标题几乎引自: 给定一个结构类型S和一个名为T的类型,升级的方法是 包含在结构的方法集中,如下所示: 如果S包含匿名字段T,则S和*S的方法集都包括接收方T的升级方法。方法集*S还包括接收方*T的升级方法 这是一个示例,表明方法inc()已升级 package main import ( "fmt" ) // just an int wrapper type integer struct { i int } func (self *integer) inc() {

问题的标题几乎引自:

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

  • 如果S包含匿名字段T,则S和*S的方法集都包括接收方T的升级方法。方法集*S还包括接收方*T的升级方法
这是一个示例,表明方法
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)
}

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

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

从:

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

从:

对于类型为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()的缩写