如何在 Go 中的切片或结构中存储不同的结构(不嵌入)
How do I STORE different structs in a slice or a struct in Go (Not embedding)
刚接触Golang,逛完A Tour of Go,想自己动手
我想要的
我想将不同类型的结构放入单个切片(或结构?),
所以我可以使用 for
循环来 将每个结构传递给函数 。
例如
在 PHP 中,我可以将我的 类 存储在一个数组中,然后像这样将它们分别传递给 foobar()
:
$classes = [$A, $B, $C, $D]; // $A, $B, $C, $D are classes (called `struct` in Golang).
foreach ($classes as $class)
foobar($class);
我试过的
我尝试在 Golang 中做同样的事情,我希望它看起来像这样:
A{B{}, C{}, D{}}
由于我使用 slice
失败,我决定使用 struct
来保存我的 structs
:
type A struct {
B
C
D
}
type B struct {
Date string
}
type C struct {
Date string
}
type D struct {
Date string
}
func main() {
// Using reflect to loop the A struct:
//
v := reflect.ValueOf(A{})
for i := 0; i < v.NumField(); i++ {
foobar(v.Field(i).Interface()) // Passing each struct to the `foobar()` function
}
}
但看起来我实际上是在嵌入而不是存储它们,请问有什么建议吗?
我认为 interface{} 是您所追求的。例如像这样:
type A struct {
data string
}
type B struct {
data int
}
func printData(s interface{}) {
switch s.(type) {
case A:
fmt.Printf("A: %s\n", s.(A).data)
case B:
fmt.Printf("B: %d\n", s.(B).data)
}
}
func main() {
classes := []interface{}{A{data: "first"}, B{data: 2}, A{data: "third"}}
for _, c := range classes {
printData(c)
}
}
这可能是您在 go 中可以达到的最接近 "duck typing" 的水平。
尽管如果您的结构真的那么相似,您最好还是定义一个公共接口并为每个结构实现该接口。这是使用接口的相同示例:
type DataGetter interface {
getDate() string
}
type A struct {
data string
}
func (a A) getDate() string {
return a.data
}
type B struct {
data int
}
func (b B) getDate() string {
return fmt.Sprintf("%d", b.data)
}
func printData(s DataGetter) {
fmt.Printf("%s\n", s.getDate())
}
func main() {
classes := []DataGetter{A{data: "first"}, B{data: 2}, A{data: "third"}}
for _, c := range classes {
printData(c)
}
}
刚接触Golang,逛完A Tour of Go,想自己动手
我想要的
我想将不同类型的结构放入单个切片(或结构?),
所以我可以使用 for
循环来 将每个结构传递给函数 。
例如
在 PHP 中,我可以将我的 类 存储在一个数组中,然后像这样将它们分别传递给 foobar()
:
$classes = [$A, $B, $C, $D]; // $A, $B, $C, $D are classes (called `struct` in Golang).
foreach ($classes as $class)
foobar($class);
我试过的
我尝试在 Golang 中做同样的事情,我希望它看起来像这样:
A{B{}, C{}, D{}}
由于我使用 slice
失败,我决定使用 struct
来保存我的 structs
:
type A struct {
B
C
D
}
type B struct {
Date string
}
type C struct {
Date string
}
type D struct {
Date string
}
func main() {
// Using reflect to loop the A struct:
//
v := reflect.ValueOf(A{})
for i := 0; i < v.NumField(); i++ {
foobar(v.Field(i).Interface()) // Passing each struct to the `foobar()` function
}
}
但看起来我实际上是在嵌入而不是存储它们,请问有什么建议吗?
我认为 interface{} 是您所追求的。例如像这样:
type A struct {
data string
}
type B struct {
data int
}
func printData(s interface{}) {
switch s.(type) {
case A:
fmt.Printf("A: %s\n", s.(A).data)
case B:
fmt.Printf("B: %d\n", s.(B).data)
}
}
func main() {
classes := []interface{}{A{data: "first"}, B{data: 2}, A{data: "third"}}
for _, c := range classes {
printData(c)
}
}
这可能是您在 go 中可以达到的最接近 "duck typing" 的水平。
尽管如果您的结构真的那么相似,您最好还是定义一个公共接口并为每个结构实现该接口。这是使用接口的相同示例:
type DataGetter interface {
getDate() string
}
type A struct {
data string
}
func (a A) getDate() string {
return a.data
}
type B struct {
data int
}
func (b B) getDate() string {
return fmt.Sprintf("%d", b.data)
}
func printData(s DataGetter) {
fmt.Printf("%s\n", s.getDate())
}
func main() {
classes := []DataGetter{A{data: "first"}, B{data: 2}, A{data: "third"}}
for _, c := range classes {
printData(c)
}
}