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

Go 如何创建嵌入另一个结构的结构片?,go,Go,我有以下资料: 我需要遍历嵌入A的所有结构,但我很难做到这一点。上述方法不起作用,“不能在数组或切片文字中使用B文字(类型*B)作为类型*A”。最好的方法是什么?在上声明满足接口的方法: func (a *A) SetName(s string) { a.Name = s } func (a *A) SetAddress(s string) { a.Address = s } 在以下范围内使用该接口的切片: for _, s := range []myinterface{&

我有以下资料:


我需要遍历嵌入A的所有结构,但我很难做到这一点。上述方法不起作用,“不能在数组或切片文字中使用B文字(类型*B)作为类型*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{}} {
   ...
}

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

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{}} {
   ...
}

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

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

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

您可以在此处阅读更多信息:

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


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

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

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

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

您可以在此处阅读更多信息:

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


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

编译器告诉您问题:不能将type
B
用作type
a
(也不能将type
a
用作type
B
);这些类型根本不一样。您应该在
myinterface
的一部分上进行测距

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

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

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

func (a *A) aSelf() *A {
    return a
}

type myinterface interface {
    SetName(string)
    SetAddress(string)
    aSelf() *A
}

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

编译器告诉您问题:不能将type
B
用作type
A
(也不能将type
A
用作type
B
);这些类型根本不一样。您应该在
myinterface
的一部分上进行测距

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

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

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

func (a *A) aSelf() *A {
    return a
}

type myinterface interface {
    SetName(string)
    SetAddress(string)
    aSelf() *A
}

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