GoLang如何对结构和嵌入式结构实现的接口进行类型转换

时间:2018-04-22 05:10:54

标签: go

我最近遇到的代码正在做一些我不理解的事情。

有多个结构具有相同的嵌入式结构,并且接口定义了返回指向每个结构的指针的方法。该接口由嵌入式结构实现,但仅部分地“接触”。通过各个结构,每个结构只实现返回指向该结构的指针的方法。

为了更好地理解,以下是代表性代码:

type Vodka struct {
    BaseAttributes

    Label string
}

func (v *Vodka) GetVodka() *Vodka {
    return v
}

然后每个单独的struct只实现返回其指针的方法,例如:

func someFunc() BarStocks {
    v := Vodka{}
    return &v
}

现在在代码中,此设置用于将单个结构类型转换为接口作为指针,如下所示:

{{1}}

现在我还没有太深入Go,因此无法理解结构的指针与接口的类型是如何相同的。

提前感谢您对此的任何见解。

2 个答案:

答案 0 :(得分:2)

我会尽力回答我认为你问过的问题。

嵌入时documentation解释了您所看到的行为,

  

嵌入与子类化不同的重要方式。   当我们嵌入一个类型时,那种类型的方法成为了方法   外部类型,但是当它们被调用时,方法的接收者是   内在的类型,而不是外在的类型。

这解释了嵌入Vodka实现BaseAttributes中所有方法的BarStocks结构如何能够满足接口Barstocks。但是,此摘录并未解释我们如何有效地覆盖GetVodka()结构的Vodka

要理解这一点,我们需要阅读文档中的另一段摘录。

  

嵌入类型引入了名称冲突问题,但引入了规则   解决它们很简单。首先,字段或方法X隐藏任何其他字段   项目X在类型的更深层嵌套部分。

此摘录说明如果Vodka实现GetVodka()并嵌入一个结构(BaseAttributes)也实现GetVodka(),则最外层定义优先。

这些行为的组合解释了Vodka如何满足BarStocks接口并具有您在示例代码中看到的行为。

答案 1 :(得分:0)

Vodka中缺少但BarStocks上存在的其他方法是为BaseAttributes实现的,如果Vodka中缺少该方法,则会调用嵌入式strut中的方法。

注意,嵌入式结构中的方法无法访问父结构成员。另请注意,如果您想在父级中定义嵌入式结构的方法(如GetVodka用于伏特加),则调用嵌入式结构的方法,然后将嵌入类型的名称添加到方法中。例如

myDrink := someFunc()
myDrink.BaseAttributes.GetVodka()

在这种情况下,这显然没有用,因为所有BaseAttribute方法都返回nil,但将来可能会有所帮助。