首页 > 解决方案 > 嵌入字段是否计入接口

问题描述

在 Golang 中,我可以在struct. 嵌入的字段得到“提升”,新struct的可以使用嵌入字段的所有功能,就好像它是它自己的一部分一样。所以我的问题是,嵌入式字段的功能是否计入接口实现?例如:

type Foo struct {
    Name string
}

func (f *Foo) Name() {
    fmt.Println(f.Name)
}

type Hello interface {
    Name()
    Hello()
}

type Bar struct {
    World string
    *Foo
}

func (b *Bar) Hello() {
    fmt.Println("Hello")
}

在上面的代码中,Bar{}没有实现名为 的函数Name(),但Foo{}确实实现了。既然Foo{}是嵌入的字段Bar{},那么是Bar{}类型Hello吗?

标签: go

解决方案


以下是如何在语言规范中追踪这一点

在“接口类型”部分了解实现接口的含义:

接口类型¶

接口类型指定称为其接口的方法集。接口类型的变量可以存储任何类型的值,方法集是接口的任何超集。据说这种类型实现了接口。

或来自“方法集”部分

类型的方法集决定了该类型实现的接口......

所以重要的是要实现接口的类型的方法集。让我们看看在嵌入字段的情况下是什么构成了方法集:

我检查的第一个地方是“方法集”部分,但它把我们送到了别处:

进一步的规则适用于包含嵌入字段的结构,如结构类型部分所述。

因此,我们转到“结构类型”部分并找到:

如果 xf 是表示该字段或方法 f 的合法选择器,则称为提升结构 x 中嵌入字段的字段或方法 f。

...

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

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

因此,鉴于嵌入字段的方法被提升,它们包含在包含结构的方法集中。正如我们在上面看到的,任何类型的方法集决定了它是否实现了一个接口。


推荐阅读