一尘不染

Golang嵌入式结构

go

是否可以在不使用嵌入式结构的情况下继承类型的方法?

代码的第一个片段是将Property结构嵌入其中的工作代码,Node我可以在上调用node.GetString该方法Properties。我不喜欢的是,当我初始化时,Node我有(?)来初始化其中的Properties结构。有没有解决的办法?

package main

import "fmt"

type Properties map[string]interface{}

func (p Properties) GetString(key string) string {
    return p[key].(string)
}

type Nodes map[string]*Node

type Node struct {
    *Properties
}

func main() {
    allNodes := Nodes{"1": &Node{&Properties{"test": "foo"}}} // :'(
    singleNode := allNodes["1"]
    fmt.Println(singleNode.GetString("test"))
}

最终,我想做以下事情。where
Node是类型Properties和初始化位置,也不需要初始化Property结构。以下代码不起作用,但可能清楚我的目标是什么。

package main

import "fmt"

type Properties map[string]interface{}

func (p Properties) GetString(key string) string {
    return p[key].(string)
}

type Nodes map[string]*Node

type Node Properties

func main() {
    allNodes := Nodes{"1": &Node{"test": "foo"}} // :)
    singleNode := allNodes["1"]
    fmt.Println(singleNode.GetString("test")) // :D
}

我将添加更多使用Properties的方法的结构,这就是我要问的原因。如果只拥有Node,我将拥有Node可以完成的方法。但是,由于我将拥有比Node我发现的更多的东西,因此可以向所有嵌入的结构添加相同的方法,这是多余的Properties

我想确切的问题,我想使用Properties方法Node而不必初始化Properties


阅读 208

收藏
2020-07-02

共1个答案

一尘不染

因此,您在这里遇到了Go的特质。嵌入是一种方法,它可以“提升”一个结构的方法以使其似乎存在于另一个结构上。尽管type Node Properties应该直观地了解这些Properties方法Node,但该语法的作用是继承其方法Node的内存布局,Properties而不是其所有方法的内存布局。

它没有解释为什么做出这种设计选择,但是Go
Spec
至少是特定的(如果干燥的话)。如果您完全按原样阅读它,没有任何解释,那么它是非常准确的:

接口类型的方法集是其接口。任何其他类型T的方法集都包含以接收者类型T声明的所有方法

GetString的接收器类型Properties不是not Node,认真地将规范解释为您是没有想象力的会计师。照这样说:

进一步的规则适用于包含匿名字段的结构,如有关结构类型的部分中所述。

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

提升的字段的作用类似于结构的普通字段,只是它们不能用作结构的复合文字中的字段名称。

给定一个结构类型S和一个名为T的类型,在该方法的方法集中包括了以下改进的方法:

  • 如果S包含匿名字段T,则S和 S的方法集都包括接收者T的提升方法。 S的方法集也包括接收者* T的提升方法。
  • 如果S包含一个匿名字段 T,则S和 S的方法集都包括接收者T或* T的提升方法。

关于复合文字的这一行迫使您Properties在每次Node创建的内容中进行声明。

ps杰夫!

2020-07-02