如何在golang中反映struct递归

时间:2015-12-28 11:54:07

标签: go go-reflect

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

以下错误。

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)
        }

    }
}

1 个答案:

答案 0 :(得分:4)

display功能中,您将valueValue声明为:

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

因此valueValue的类型为interface{}。在for循环中,您有一个递归调用display

display(&valueValue)

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

如果你想用一个指向struct的指针来调用display,你可以这样做:

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