【问题标题】:How to reflect struct recursive in golang如何在golang中反映结构递归
【发布时间】:2015-12-28 11:54:06
【问题描述】:

我想递归地反映结构类型和值,但它失败了。我不知道如何递归地传递子结构。

以下错误。

panic: reflect: NumField of non-struct type

goroutine 1 [running]:
reflect.(*rtype).NumField(0xc0b20, 0xc82000a360)
    /usr/local/go/src/reflect/type.go:660 +0x7b

我有两个结构 PersonName

type Person struct {
    Fullname NameType
    Sex      string
}

type Name struct {
    Firstname string
    Lastname  string
}

我在main中定义Person,并用递归函数显示结构体。

person := Person{
    Name{"James", "Bound"},
    "Male",
}

display(&person)

display 函数递归显示结构体。

func display(s interface{}) {
    reflectType := reflect.TypeOf(s).Elem()
    reflectValue := reflect.ValueOf(s).Elem()

    for i := 0; i < reflectType.NumField(); i++ {
        typeName := reflectType.Field(i).Name

        valueType := reflectValue.Field(i).Type()
        valueValue := reflectValue.Field(i).Interface()

        switch reflectValue.Field(i).Kind() {
        case reflect.String:
            fmt.Printf("%s : %s(%s)\n", typeName, valueValue, valueType)
        case reflect.Int32:
            fmt.Printf("%s : %i(%s)\n", typeName, valueValue, valueType)
        case reflect.Struct:
            fmt.Printf("%s : it is %s\n", typeName, valueType)
            display(&valueValue)
        }

    }
}

【问题讨论】:

标签: go go-reflect


【解决方案1】:

在您的 display 函数中,您将 valueValue 声明为:

valueValue := reflectValue.Field(i).Interface()

所以valueValue 的类型是interface{}。在 for 循环中,您可以递归调用 display

display(&valueValue)

所以它是用*interface{} 类型的参数调用的。在递归调用中,reflectType 将代表interface{},而不是恰好存储在值中的类型。由于NumField 只能在reflect.Type 的代表结构上调用,你会感到恐慌。

如果你想用指向结构的指针来调用 display,你可以这样做:

v := valueValue := reflectValue.Field(i).Addr()
display(v.Interface())

【讨论】:

  • @完全正确。对reflect我很困惑,有reflect.TypeOf、reflect.ValueOf等等很多方法。我需要更多时间来调查他们。 :)
  • 是否可以在“显示”函数中修改结构值? @詹姆斯亨斯特里奇
猜你喜欢
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-28
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多