如何在golang中反映结构递归 [英] How to reflect struct recursive in golang

查看:1005
本文介绍了如何在golang中反映结构递归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



它错误如下。

  

I有两个struct Person 名称

 类型Person结构{
全名NameType
性别字符串
}

类型名称struct {
名字字符串
姓氏字符串
}

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

  person:= Person {
Name {James ,绑定},
男,
}

显示(&人)
$ b $ 显示函数递归显示结构体。

  func display(s int ())
reflectType:= reflect.TypeOf(s).Elem()
reflectValue:= reflect.ValueOf(s).Elem()

for i: = 0;我< 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)\\\
,typeName,valueValue,valueType )
case reflect.Struct:
fmt.Printf(%s:它是%s\\\
,typeName,valueType)
display(& valueValue)
}


$ b


解决方案

显示函数中,您声明 valueValue 为:

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

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

 显示(& valueValue)

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



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

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


I want to reflect the struct type and value recursively, but it fails. I don't know how to pass the sub struct recursively.

It error the following.

panic: reflect: NumField of non-struct type

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

I have two struct Person and Name

type Person struct {
    Fullname NameType
    Sex      string
}

type Name struct {
    Firstname string
    Lastname  string
}

I define the Person in main, and display the struct with recursive function.

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

display(&person)

The display function recursive display the struct.

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

    }
}

解决方案

Inside your display function, you declare valueValue as:

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

So valueValue is of type interface{}. Inside the for loop, you have a recursive call to display:

display(&valueValue)

So it is being called with an argument of type *interface{}. Inside the recursive call, reflectType will represent interface{} rather than the type that happens to be stored within the value. Since NumField can only be called on reflect.Type's representing structs, you get a panic.

If you want to call display with a pointer to the struct instead, you could do so with something like this:

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

这篇关于如何在golang中反映结构递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆