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

 mnuee 发布于 2023-02-13 10:13

这个问题的标题几乎是从golang规范中引用的:

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

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

这是一个go操场,显示该方法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)
}

Stephen Wein.. 7

没有*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()的简写

将两者放在一起,你就得到了答案.计数器是可寻址的,&计数器包含*T的方法集.因此,counter.Inc()是(&counter).Inc()的简写.

1 个回答
  • 没有*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()的简写

    将两者放在一起,你就得到了答案.计数器是可寻址的,&计数器包含*T的方法集.因此,counter.Inc()是(&counter).Inc()的简写.

    2023-02-13 10:15 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有