英文:
Iterate over mixed type slice
问题
你可以使用类型断言来访问每种结构体的字段。类型断言允许你将接口类型转换为具体的结构体类型,并访问其字段。
在你的代码中,你可以使用类型断言来访问每个结构体的字段。以下是修改后的代码示例:
package main
import "fmt"
type X struct {
Type string
Num int
}
type Y struct {
Type string
Num int
}
type Z struct {
Type string
Num int
}
func main() {
var items []interface{}
x := X{Type: "X-type", Num: 1}
items = append(items, x)
y := Y{Type: "Y-type", Num: 2}
items = append(items, y)
z := Z{Type: "Z-type", Num: 3}
items = append(items, z)
for _, item := range items {
fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
switch item := item.(type) {
case X:
fmt.Println(item.Num) // Access X struct field
fmt.Println(item.Type) // Access X struct field
case Y:
fmt.Println(item.Num) // Access Y struct field
fmt.Println(item.Type) // Access Y struct field
case Z:
fmt.Println(item.Num) // Access Z struct field
fmt.Println(item.Type) // Access Z struct field
}
}
}
通过使用类型断言,你可以根据具体的结构体类型访问每个结构体的字段。在上面的示例中,我们使用了switch
语句来检查每个item
的类型,并根据类型访问相应的字段。
英文:
I need to have different types of structs in a slice. But I can't access the field values of each struct.
package main
import "fmt"
type X struct {
Type string
Num int
}
type Y struct {
Type string
Num int
}
type Z struct {
Type string
Num int
}
func main() {
var items []interface{}
x := X{Type: "X-type", Num: 1}
items = append(items, x)
y := Y{Type: "Y-type", Num: 2}
items = append(items, y)
z := Z{Type: "Z-type", Num: 3}
items = append(items, z)
for _, item := range items {
fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
//fmt.Println(item.Num) // item.Num undefined (type interface{} has no field or method Num)
//fmt.Println(item.Type) // item.Type undefined (type interface{} has no field or method Type)
}
}
How can I access the individual fields for each type of struct?
答案1
得分: 1
有几种选择。
使用类型开关(type switch):
for _, item := range items {
switch item := item.(type) {
case X:
fmt.Printf("X: %d\n", item.Num)
case Y:
fmt.Printf("Y: %d\n", item.Num)
case Z:
fmt.Printf("Z: %d\n", item.Num)
default:
// 添加处理不支持类型的代码
}
}
使用反射包按名称访问字段:
for _, item := range items {
fmt.Println(reflect.ValueOf(item).FieldByName("Num").Interface().(int))
}
使用接口:
为每种类型添加一个访问器方法:
func (x X) GetNum() int { return x.Num }
func (y Y) GetNum() int { return y.Num }
func (z Z) GetNum() int { return z.Num }
声明一个接口:
type GetNumer interface {
GetNum() int
}
使用接口:
var items []GetNumer
x := X{Type: "X-type", Num: 1}
items = append(items, x)
...
for _, item := range items {
fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
fmt.Println(item.GetNum())
}
英文:
There are a couple of options.
Use a type switch:
for _, item := range items {
switch item := item.(type) {
case X:
fmt.Printf("X: %d\n", item.Num)
case Y:
fmt.Printf("Y: %d\n", item.Num)
case Z:
fmt.Printf("Z: %d\n", item.Num)
default:
// add code to handle unsupported type
}
}
Use the reflect package to access the fields by name:
for _, item := range items {
fmt.Println(reflect.ValueOf(item).FieldByName("Num").Interface().(int))
}
Use interfaces:
Add an accessor method to each type:
func (x X) GetNum() int { return x.Num }
func (y Y) GetNum() int { return y.Num }
func (z Z) GetNum() int { return z.Num }
Declare an interface:
type GetNumer interface {
GetNum() int
}
Use the interface:
var items []GetNumer
x := X{Type: "X-type", Num: 1}
items = append(items, x)
...
for _, item := range items {
fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
fmt.Println(item.GetNum())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论