如何创建一个嵌入另一个结构的片段?

时间:2017-07-14 02:14:27

标签: go

我有以下内容:

https://play.golang.org/p/q2NUMzbw6-

package main

import "fmt"

type A struct {
    Name string
    Address string
}

type B struct {
    A
}

type C struct {
    A
}

type D struct {
    A
}

//....more structs that embed A

type myinterface interface {
    SetName(string)
    SetAddress(string)
}

func run() *A {
    // iterate over a slice of structs that embed A.... how????
    for _, s := range []*A{
        &B{}, &C{}, &D{},
    } {
        s.SetName("Bob")
        s.SetAddress("Maine")
        // do some other stuff that gets very verbose w/out a slice...
        return s.A
    }
}

func main() {
    a := run()
    fmt.Println(a)
}

我需要遍历嵌入A的所有结构,但我很难这样做。以上不起作用“不能使用B字面(类型* B)作为类型* A在数组或切片文字中”。什么是最好的方式?

3 个答案:

答案 0 :(得分:1)

在A上声明满足接口的方法:

func (a *A) SetName(s string) {
    a.Name = s
}

func (a *A) SetAddress(s string) {
    a.Address = s
}

在范围内使用该界面的切片:

for _, s := range []myinterface{&B{}, &C{}, &D{}} {
   ...
}

playground example

答案 1 :(得分:1)

认为Go中的类型嵌入类似于其他语言中的继承是一种常见的误解。

事实上,类型嵌入类似于其他语言的组合。

在您的示例中,类型BA之间没有任何关联,除了通过在A中嵌入B您可以调用{{ {1}}直接在A上的方法。

您可以在此处详细了解:

F12 Developer Tools

为了模仿“继承”,你需要使用接口。

您应该使用B作为数组类型,以便以通用方式处理所有这些结构。

答案 2 :(得分:0)

编译器会告诉您问题:您不能将B类型用作A类型(并且您也不能将类型A用作类型B) ;类型简直不一样。你应该超过一片myinterface

但是,这不是整个解决方案,因为s.A不起作用,因为s现在具有myinterface类型(基础类型*B*C*D),并且名为A的方法不属于myinterface

您可以通过向aSelf() *A添加另一个方法myinterface并使用仅返回接收方的接收方类型aSelf实现*A来解决此问题。这样,BC等都可以使用此方法。请注意,您不能简单地在此实例中为方法A命名,因为B.A(和C.A等)将不明确:.A是否引用嵌入式{ {1}}字段本身或嵌入式A字段的A方法?如果不导出方法,则可以将其命名为A,否则您需要使用其他名称,例如前面提到的a

以下是要更改/添加的相关位:

aSelf

Playground link