遍历混合类型的切片

huangapple go评论120阅读模式
英文:

Iterate over mixed type slice

问题

你可以使用类型断言来访问每种结构体的字段。类型断言允许你将接口类型转换为具体的结构体类型,并访问其字段。

在你的代码中,你可以使用类型断言来访问每个结构体的字段。以下是修改后的代码示例:

  1. package main
  2. import "fmt"
  3. type X struct {
  4. Type string
  5. Num int
  6. }
  7. type Y struct {
  8. Type string
  9. Num int
  10. }
  11. type Z struct {
  12. Type string
  13. Num int
  14. }
  15. func main() {
  16. var items []interface{}
  17. x := X{Type: "X-type", Num: 1}
  18. items = append(items, x)
  19. y := Y{Type: "Y-type", Num: 2}
  20. items = append(items, y)
  21. z := Z{Type: "Z-type", Num: 3}
  22. items = append(items, z)
  23. for _, item := range items {
  24. fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
  25. switch item := item.(type) {
  26. case X:
  27. fmt.Println(item.Num) // Access X struct field
  28. fmt.Println(item.Type) // Access X struct field
  29. case Y:
  30. fmt.Println(item.Num) // Access Y struct field
  31. fmt.Println(item.Type) // Access Y struct field
  32. case Z:
  33. fmt.Println(item.Num) // Access Z struct field
  34. fmt.Println(item.Type) // Access Z struct field
  35. }
  36. }
  37. }

通过使用类型断言,你可以根据具体的结构体类型访问每个结构体的字段。在上面的示例中,我们使用了switch语句来检查每个item的类型,并根据类型访问相应的字段。

英文:

I need to have different types of structs in a slice. But I can't access the field values of each struct.

  1. package main
  2. import "fmt"
  3. type X struct {
  4. Type string
  5. Num int
  6. }
  7. type Y struct {
  8. Type string
  9. Num int
  10. }
  11. type Z struct {
  12. Type string
  13. Num int
  14. }
  15. func main() {
  16. var items []interface{}
  17. x := X{Type: "X-type", Num: 1}
  18. items = append(items, x)
  19. y := Y{Type: "Y-type", Num: 2}
  20. items = append(items, y)
  21. z := Z{Type: "Z-type", Num: 3}
  22. items = append(items, z)
  23. for _, item := range items {
  24. fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
  25. //fmt.Println(item.Num) // item.Num undefined (type interface{} has no field or method Num)
  26. //fmt.Println(item.Type) // item.Type undefined (type interface{} has no field or method Type)
  27. }
  28. }

How can I access the individual fields for each type of struct?

答案1

得分: 1

有几种选择。

使用类型开关(type switch):

  1. for _, item := range items {
  2. switch item := item.(type) {
  3. case X:
  4. fmt.Printf("X: %d\n", item.Num)
  5. case Y:
  6. fmt.Printf("Y: %d\n", item.Num)
  7. case Z:
  8. fmt.Printf("Z: %d\n", item.Num)
  9. default:
  10. // 添加处理不支持类型的代码
  11. }
  12. }

使用反射包按名称访问字段:

  1. for _, item := range items {
  2. fmt.Println(reflect.ValueOf(item).FieldByName("Num").Interface().(int))
  3. }

使用接口:

为每种类型添加一个访问器方法:

  1. func (x X) GetNum() int { return x.Num }
  2. func (y Y) GetNum() int { return y.Num }
  3. func (z Z) GetNum() int { return z.Num }

声明一个接口:

  1. type GetNumer interface {
  2. GetNum() int
  3. }

使用接口:

  1. var items []GetNumer
  2. x := X{Type: "X-type", Num: 1}
  3. items = append(items, x)
  4. ...
  5. for _, item := range items {
  6. fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
  7. fmt.Println(item.GetNum())
  8. }
英文:

There are a couple of options.

Use a type switch:

  1. for _, item := range items {
  2. switch item := item.(type) {
  3. case X:
  4. fmt.Printf("X: %d\n", item.Num)
  5. case Y:
  6. fmt.Printf("Y: %d\n", item.Num)
  7. case Z:
  8. fmt.Printf("Z: %d\n", item.Num)
  9. default:
  10. // add code to handle unsupported type
  11. }
  12. }

Use the reflect package to access the fields by name:

  1. for _, item := range items {
  2. fmt.Println(reflect.ValueOf(item).FieldByName("Num").Interface().(int))
  3. }

Use interfaces:

Add an accessor method to each type:

  1. func (x X) GetNum() int { return x.Num }
  2. func (y Y) GetNum() int { return y.Num }
  3. func (z Z) GetNum() int { return z.Num }

Declare an interface:

  1. type GetNumer interface {
  2. GetNum() int
  3. }

Use the interface:

  1. var items []GetNumer
  2. x := X{Type: "X-type", Num: 1}
  3. items = append(items, x)
  4. ...
  5. for _, item := range items {
  6. fmt.Println(item) //{X-type 1} {Y-type 2} {Z-type 3}
  7. fmt.Println(item.GetNum())
  8. }

huangapple
  • 本文由 发表于 2023年3月2日 03:52:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75608324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定