GoLang 的类型转换到由结构和嵌入结构实现的接口如何工作



我最近遇到了一个我不理解的代码。

有多个具有相同嵌入式结构的结构和一个定义将指针返回到每个结构的方法的接口。该界面由嵌入式结构实现,但仅由单个结构"部分地"实现,因此,每个结构仅实现了返回该结构指针的方法。

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

type BarStocks interface {
    GetVodka() *Vodka
    GetMartini() *Martini
    GetBourbon() *Bourbon
    GetNegroni() *Negroni
    GetManhattan() *Manhattan
}
type BaseAttributes struct {
    ID        uuid.UUID
    Quantity float64
    CreatedAt time.Time
    UpdatedAt time.Time
}
func (e *BaseAttributes) GetVodka() *Vodka {
    return nil
}
func (e *BaseAttributes) GetMartini() *Martini {
    return nil
}
func (e *BaseAttributes) GetBourbon() *Bourbon {
    return nil
}
func (e *BaseAttributes) GetNegroni() *Negroni {
    return nil
}
func (e *BaseAttributes) GetManhattan() *Manhattan {
    return nil
}

,然后每个构造仅实现返回指针的方法,例如:

type Vodka struct {
    BaseAttributes
    Label string
}
func (v *Vodka) GetVodka() *Vodka {
    return v
}

现在,在代码中,此设置用于将单个结构作为指针打字到接口,类似的内容:

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

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

事先感谢您对此的任何见解。

我会尽力回答我认为您要问的问题。

有关嵌入的文档解释了您看到的行为,

有一种重要方法与子类别不同。 当我们嵌入类型时,该类型的方法成为 外部类型,但是当它们被调用时,该方法的接收器是 内部类型,而不是外部类型。

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

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

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

此摘录解释说,如果Vodka实现GetVodka()并嵌入了一个结构(BaseAttributes)也实现GetVodka(),则最外部的定义是优先的定义。

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

伏特加(Vodka(缺少的其他方法,但在baseatottributes上实现了barstocks上的其他方法,如果伏特加(Vodka(缺少该方法,则将调用来自嵌入式支柱的方法。

注意,嵌入式结构中的方法将无法访问父结构成员。另请注意,如果您想在父母中定义嵌入式结构的方法(因为GetVodka为Vodka(,则您将对该方法的嵌入式类型的名称进行预处理。例如

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

这在这种情况下显然没有帮助

最新更新