【问题标题】:Can One Embed A Struct In A Struct To Satisfy An Interface可以在结构中嵌入结构来满足接口吗
【发布时间】:2014-05-06 03:35:24
【问题描述】:

我有以下代码(也可在Go Playground 中找到)。是否可以实例化一个 A 结构,使其包含嵌入式 C、S 和 X。我使用接口的原因是,根据我调用的 Build 函数,我希望结构具有不同的实现酒吧()。我可以有一个 S1 或一个 S2,其中 Bar() 略有不同,但都是 S'ers。

package main

import "fmt"

type Cer interface {
    Foo()
}

type Ser interface {
    Bar()
}

type Aer interface {
    Cer
    Ser
}

type C struct {
    CField string
}

func (this *C) Foo() {
}

type S struct {
    SField string
}

func (this *S) Bar() {
}

type X struct {
    XField string
}

type A struct {
    Cer
    Ser
    X
}

func main() {
    x := new(X)
    a := Build(x)
    fmt.Println(a)
}

func Build(x *X) A {
    a := new(A)
    a.X = *x
    a.XField = "set x"
    return *a
}

【问题讨论】:

  • 如果你想在 A 中嵌入一个 A,你需要在某个时候使用一个指针类型(一个结构不能有它自己的值类型作为一个字段)。
  • 对不起。我想嵌入 C、S 和 X。我更新了问题。谢谢你的收获。 Build() 函数嵌入了一个 X;我已经学会了如何在 Go 中做到这一点。但是,我想知道如何在其中获得 C 和 S。

标签: interface struct go embedding


【解决方案1】:

简短的回答是:可以。

但是当嵌入接口时,如果你在没有先给值的情况下尝试调用嵌入的方法,则会出现运行时错误。

所以,以下工作正常:

a := Build(x)
// Removing the line below will cause a runtime error when calling a.Foo()
a.Cer = &C{"The CField"}
a.Foo() 

【讨论】:

  • 我在这里建立了播放链接:play.golang.org/p/Jo0a20gqMZ。可以看到你的A实例满足接口。
  • dethtron500 是的,它确实满足它。但是在给 a.Cer 一个值之前,您不能调用方法 a.Foo()。以类似的方式,这将不起作用:s := fmt.Stringer(nil); fmt.Println(s.String())
  • 嗯。我试图在 Build 中使用 new(C) 这样做,但这不起作用。我在 new() 和 &C{""} 之间缺少什么细微差别?请参阅 play.golang.org/p/8InbCFaufX中的 Build()
  • @alphadogg new(C)&C{} 之间没有区别。因此,在 Build() 中,这应该可以工作:a.Cer = new(C)
  • @alphadogg playground link 中的编译错误是因为如果不先进行类型断言,就无法访​​问存储在接口中的结构的字段。所以你的行应该看起来像:a.Cer.(*C).CField = "set c"。如果所有 Cer 也应该有一个 CField,那么您应该创建像 SetCField() 这样的 Cer 方法。
猜你喜欢
  • 2018-01-13
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多