go - 结构嵌入提升方法问题中的结构
问题描述
package main
import "fmt"
type type1 struct { //T
}
func (t1 type1) type1Meth1() {
fmt.Printf("==> func (t1 type1) type1Meth1():\n Type: %T\n Value: %+v\n\n", t1, t1)
}
func (t1 *type1) type1Meth2() {
fmt.Printf("==> func (t1 *type1) type1Meth2():\n Type: %T\n Value: %p\n Contains: %+v\n\n", t1, t1, t1)
}
func (t1 type1) type1Meth3() {
fmt.Printf("==> func (t1 type1) type1Meth3():\n Type: %T\n Value: %+v\n", t1, t1)
}
type type2 struct { //S
type1
}
func (t2 *type2) type1Meth3() {
fmt.Printf("==> func (t2 *type2) type1Meth3(): Type: %T\n Value: %+v\n\n", t2, t2)
}
func main() {
t2 := type2{}
t2.type1Meth1() // type2 contains method set of type1
t2.type1Meth2() // not sure, why this works? type2 does not have method set of *type1 (A)
t2.type1Meth3() // type2 contains method set of type1. intercepted by embedding type type2 and called with *type2 receiver
}
给我:
$ go run embed-struct-in-struct.go
==> func (t1 type1) type1Meth1():
Type: main.type1
Value: {}
==> func (t1 *type1) type1Meth2():
Type: *main.type1
Value: 0x116be80
Contains: &{}
==> func (t2 *type2) type1Meth3(): Type: *main.type2
Value: &{type1:{}}
go version
go version go1.17.2 darwin/amd64
不确定为什么调用 (A) 有效?文档说:提升的方法包含在结构的方法集中,如下所示:
给定一个结构类型 S 和一个定义类型 T,提升的方法包含在结构的方法集中,如下所示:
如果 S 包含嵌入字段 T,则 S 和 *S 的方法集都包含带有接收者 T 的提升方法。*S 的方法集还包括带有接收者 *T 的提升方法。如果 S 包含嵌入字段 *T,则 S 和 *S 的方法集都包含带有接收器 T 或 *T 的提升方法。
解决方案
(A) 有效,因为方法调用隐含地获取接收者的地址。
该方法根据问题中引用的提升规则进行提升(*type1).type1Meth2()
。*type2
关于调用的规范部分说 :
如果 x 的(类型)的方法集包含 m 并且参数列表可以分配给 m 的参数列表,则方法调用 xm() 是有效的。如果 x 是可寻址的并且 &x 的方法集包含 m,则 xm() 是 (&x).m() 的简写:
该表达式t2.type1Meth2()
是(&t2).type1Meth2()
因为t2
是可寻址的并且type1Meth2()
在 的方法集中的简写*type2
。
推荐阅读
- swift - 斯威夫特:SecRandomCopyBytes 会失败吗?
- aerospike - 如何以原子方式更新 Aerospike 中的地图键?
- apache-superset - Superset 仪表板上的问题:意外错误 504
- java - 如何在 RSyntaxTextArea 行上添加运行按钮
- pip - 安装 fbprophet 时出现 pip 安装错误
- python - 使用 python 在 kivy 中遇到错误“无法找到任何有价值的窗口提供程序”
- google-cloud-platform - Google Cloud (GCP) 设置多集群入口 - gcloud 命令“gcloud alpha container hub ingress enable \ --config-membership”出错
- python - 如何在不出现 TokenError 的情况下使用 Python fernet 加密和解密文件?
- python - django 应用程序监听 localhost:8000 与 0.0.0.0:8000
- python - TelegramBot 授权