Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
golang递归地反映字段和值的类型_Go_Reflection - Fatal编程技术网

golang递归地反映字段和值的类型

golang递归地反映字段和值的类型,go,reflection,Go,Reflection,在golang中,我希望通过一个结构递归地反映,得到字段的名称、类型和值 这里的代码帮助我思考 问题是,当我试图提取值时,当我在ptr值上反映该值时,我总是感到恐慌。 是否可以同时反映这两种类型,并一直传递值,直到到达基本体,然后打印字段名、类型和值 以下是我修改的代码: func printType(前缀字符串,t reflect.Type,v reflect.Value映射[reflect.Type]bool){ //打印此类型的名称(用于说明)。 fmt.Printf(“%s”(,t)

在golang中,我希望通过一个结构递归地反映,得到字段的名称、类型和值

这里的代码帮助我思考

问题是,当我试图提取值时,当我在ptr值上反映该值时,我总是感到恐慌。 是否可以同时反映这两种类型,并一直传递值,直到到达基本体,然后打印字段名、类型和值

以下是我修改的代码:

func printType(前缀字符串,t reflect.Type,v reflect.Value映射[reflect.Type]bool){
//打印此类型的名称(用于说明)。
fmt.Printf(“%s”(,t)
//遍历元素,边走边添加到描述中。
要素:
为了{
开关t.Kind(){
案例反映。Ptr:
格式打印(“ptr to”)
case reflect.Slice:
格式打印(“切片”)
case reflect.Array:
fmt.Printf(“包含%d个元素的数组”,t.Len())
违约:
破除元素
}
t=t.Elem()
}
//打印描述的类型和结尾)。
//对于结构,我们打印字段的名称并递归。
开关t.Kind(){
case reflect.Struct:
fmt.Printf(“具有%d个字段的结构)\n”,t.NumField()
如果访问[t]{
//不要吹嘘递归类型定义。
打破
}
已访问[t]=true
前缀+=“”
对于i:=0;i
当我运行此命令时,调用fieldValue:=v.Field(I)时会感到恐慌 关于如何实现这一点有什么想法吗

谢谢

试试这个:

func printValue(prefix string, v reflect.Value, visited map[interface{}]bool) {

    fmt.Printf("%s: ", v.Type())

    // Drill down through pointers and interfaces to get a value we can print.
    for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
        if v.Kind() == reflect.Ptr {
            // Check for recursive data
            if visited[v.Interface()] {
                fmt.Println("visted")
                return
            }
            visited[v.Interface()] = true
        }
        v = v.Elem()
    }

    switch v.Kind() {
    case reflect.Slice, reflect.Array:
        fmt.Printf("%d elements\n", v.Len())
        for i := 0; i < v.Len(); i++ {
            fmt.Printf("%s%d: ", prefix, i)
            printValue(prefix+"   ", v.Index(i), visited)
        }
    case reflect.Struct:
        t := v.Type() // use type to get number and names of fields
        fmt.Printf("%d fields\n", t.NumField())
        for i := 0; i < t.NumField(); i++ {
            fmt.Printf("%s%s: ", prefix, t.Field(i).Name)
            printValue(prefix+"   ", v.Field(i), visited)
        }
    case reflect.Invalid:
        fmt.Printf("nil\n")
    default:
        fmt.Printf("%v\n", v.Interface())
    }
}
func printValue(前缀字符串,v reflect.Value,已访问映射[接口{}]bool){
fmt.Printf(“%s:,v.Type())
//向下钻取指针和接口,以获得可以打印的值。
对于v.Kind()==reflect.Ptr | | v.Kind()==reflect.Interface{
如果v.Kind()==reflect.Ptr{
//检查递归数据
如果访问[v.Interface()]{
fmt.Println(“参观”)
返回
}
已访问[v.Interface()]=true
}
v=v.Elem()
}
开关v.种类(){
case reflect.Slice,reflect.Array:
fmt.Printf(“%d个元素\n”,v.Len())
对于i:=0;i
因为可以从值中获取类型,所以不需要将类型传递给print函数

试试这个:

func printValue(prefix string, v reflect.Value, visited map[interface{}]bool) {

    fmt.Printf("%s: ", v.Type())

    // Drill down through pointers and interfaces to get a value we can print.
    for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
        if v.Kind() == reflect.Ptr {
            // Check for recursive data
            if visited[v.Interface()] {
                fmt.Println("visted")
                return
            }
            visited[v.Interface()] = true
        }
        v = v.Elem()
    }

    switch v.Kind() {
    case reflect.Slice, reflect.Array:
        fmt.Printf("%d elements\n", v.Len())
        for i := 0; i < v.Len(); i++ {
            fmt.Printf("%s%d: ", prefix, i)
            printValue(prefix+"   ", v.Index(i), visited)
        }
    case reflect.Struct:
        t := v.Type() // use type to get number and names of fields
        fmt.Printf("%d fields\n", t.NumField())
        for i := 0; i < t.NumField(); i++ {
            fmt.Printf("%s%s: ", prefix, t.Field(i).Name)
            printValue(prefix+"   ", v.Field(i), visited)
        }
    case reflect.Invalid:
        fmt.Printf("nil\n")
    default:
        fmt.Printf("%v\n", v.Interface())
    }
}
func printValue(前缀字符串,v reflect.Value,已访问映射[接口{}]bool){
fmt.Printf(“%s:,v.Type())
//向下钻取指针和接口,以获得可以打印的值。
对于v.Kind()==reflect.Ptr | | v.Kind()==reflect.Interface{
如果v.Kind()==reflect.Ptr{
//检查递归数据
如果访问[v.Interface()]{
fmt.Println(“参观”)
返回
}
已访问[v.Interface()]=true
}
v=v.Elem()
}
开关v.种类(){
case reflect.Slice,reflect.Array:
fmt.Printf(“%d个元素\n”,v.Len())
对于i:=0;i
因为可以从值中获取类型,所以不需要将类型传递给print函数


非常有用的例子,谢谢!非常有用的例子,谢谢!