我有以下内容:
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在数组或切片文字中”。什么是最好的方式?
答案 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{}} {
...
}
答案 1 :(得分:1)
认为Go中的类型嵌入类似于其他语言中的继承是一种常见的误解。
事实上,类型嵌入类似于其他语言的组合。
在您的示例中,类型B
和A
之间没有任何关联,除了通过在A
中嵌入B
您可以调用{{ {1}}直接在A
上的方法。
您可以在此处详细了解:
为了模仿“继承”,你需要使用接口。
您应该使用B
作为数组类型,以便以通用方式处理所有这些结构。
答案 2 :(得分:0)
编译器会告诉您问题:您不能将B
类型用作A
类型(并且您也不能将类型A
用作类型B
) ;类型简直不一样。你应该超过一片myinterface
。
但是,这不是整个解决方案,因为s.A
不起作用,因为s
现在具有myinterface
类型(基础类型*B
,*C
和*D
),并且名为A
的方法不属于myinterface
。
您可以通过向aSelf() *A
添加另一个方法myinterface
并使用仅返回接收方的接收方类型aSelf
实现*A
来解决此问题。这样,B
,C
等都可以使用此方法。请注意,您不能简单地在此实例中为方法A
命名,因为B.A
(和C.A
等)将不明确:.A
是否引用嵌入式{ {1}}字段本身或嵌入式A
字段的A
方法?如果不导出方法,则可以将其命名为A
,否则您需要使用其他名称,例如前面提到的a
。
以下是要更改/添加的相关位:
aSelf