【问题标题】:Struct in struct embedding promoted methods question结构嵌入提升方法问题中的结构
【发布时间】:2021-12-15 19:42:35
【问题描述】:
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) 有效? 文档说:promoted methods are included in the method set of the struct as follows:

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

如果 S 包含嵌入字段 T,则 S 和 *S 的方法集都包含带有接收者 T 的提升方法。*S 的方法集还包括带有接收者 *T 的提升方法。 如果 S 包含嵌入字段 *T,则 S 和 *S 的方法集都包含带有接收者 T 或 *T 的提升方法。

【问题讨论】:

    标签: go struct embedding


    【解决方案1】:

    (A) 有效,因为方法调用隐式获取接收者的地址。

    根据问题中引用的提升规则,方法(*type1).type1Meth2() 被提升为*type2

    section of the specification on calls 说:

    如果 x 的(类型)的方法集包含 m 并且参数列表可以分配给 m 的参数列表,则方法调用 x.m() 是有效的。如果 x 是可寻址的并且 &x 的方法集包含 m,则 x.m() 是 (&x).m() 的简写:

    表达式t2.type1Meth2()(&t2).type1Meth2() 的简写,因为t2 是可寻址的,而type1Meth2()*type2 的方法集中。

    【讨论】:

    • 哇很有趣。方法集包含的规则并不简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多