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
在Go中递归打印映射中的所有值_Go - Fatal编程技术网

在Go中递归打印映射中的所有值

在Go中递归打印映射中的所有值,go,Go,假设我有一张这种类型的地图: var results map[string]interface{} 这些值可以是任何东西,甚至是另一个映射。如何打印所有值?如果该值是一个数组,我想单独打印数组中的每个项目。如果它是另一个地图,我想递归调用地图上的同一个函数。不久前我无耻地从一个网站上撕下了这个: import ( "fmt" "reflect" "strings" ) /* InspectStruct prints the guts of an instantiate

假设我有一张这种类型的地图:

var results map[string]interface{}

这些值可以是任何东西,甚至是另一个映射。如何打印所有值?如果该值是一个数组,我想单独打印数组中的每个项目。如果它是另一个地图,我想递归调用地图上的同一个函数。

不久前我无耻地从一个网站上撕下了这个:

import (
    "fmt"
    "reflect"
    "strings"
)

/*
InspectStruct prints the guts of an instantiated struct. Very handy for debugging
usage: InspectStruct(req, 0) -> prints all children
*/

func InspectStructV(val reflect.Value, level int) {
    if val.Kind() == reflect.Interface && !val.IsNil() {
        elm := val.Elem()
        if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
            val = elm
        }
    }
    if val.Kind() == reflect.Ptr {
        val = val.Elem()
    }

    for i := 0; i < val.NumField(); i++ {
        valueField := val.Field(i)
        typeField := val.Type().Field(i)
        address := "not-addressable"

        if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
            elm := valueField.Elem()
            if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
                valueField = elm
            }
        }

        if valueField.Kind() == reflect.Ptr {
            valueField = valueField.Elem()

        }
        if valueField.CanAddr() {
            address = fmt.Sprintf("0x%X", valueField.Addr().Pointer())
        }

        fmt.Printf("%vField Name: %s,\t Field Value: %v,\t Address: %v\t, Field type: %v\t, Field kind: %v\n",
            strings.Repeat("\t", level),
            typeField.Name,
            //valueField.Interface(),
            address,
            typeField.Type,
            valueField.Kind())

        if valueField.Kind() == reflect.Struct {
            InspectStructV(valueField, level+1)
        }
    }
}

func InspectStruct(v interface{}, level int) {
    InspectStructV(reflect.ValueOf(v), level)
}
导入(
“fmt”
“反映”
“字符串”
)
/*
InspectStruct打印实例化结构的内部。非常方便调试
用法:InspectStruct(req,0)->打印所有子项
*/
func InspectStructV(val reflect.Value,级别int){
如果val.Kind()==reflect.Interface&!val.IsNil(){
elm:=val.Elem()
如果elm.Kind()==reflect.Ptr&&!elm.IsNil()&&elm.Elem().Kind()==reflect.Ptr{
瓦尔=埃尔姆
}
}
如果val.Kind()==reflect.Ptr{
val=val.Elem()
}
对于i:=0;i
在fmt上使用%v。Printf将遍历内部映射并打印元素 也可以通过对每个字符串调用String()。现在,如果要更改内部类型的默认打印,只需在该类型上实现String()。在下面的示例中,我创建了[]int的一个版本,它每行打印一个int

package main

import (
    "fmt"
    "strings"
)

type OnePerLineInt []int

func (ip OnePerLineInt) String() string {
    var ret []string
    for _, a := range ip {
        ret = append(ret, fmt.Sprintf("Item: %v\n", a))
    }
    return strings.Join(ret, "")
}

func main() {
    arr := &OnePerLineInt{1, 2, 3}
    arr1 := []int{4, 5 , 6}
    foo := make(map[string]interface{})
    bar := make(map[string]interface{})
    bar["a"] = "foobar1"
    bar["b"] = "foobar2"
    foo["1"] = arr
    foo["2"] = bar
    foo["3"] = arr1
    fmt.Printf("foo contents: %v\n", foo)
    fmt.Printf("bar is :%v\n", bar)
}
印刷品:

foo contents: map[1:Item: 1
Item: 2
Item: 3
2:map[a:foobar1 b:foobar2] 3:[4 5 6]]
bar is :map[a:foobar1 b:foobar2]

您是否只想打印它以检查其中的数据?您是否尝试过
fmt
软件包提供的各种输出?封送到json对您有用吗?@sberry我不想检查其中的数据,我只想比较两个任意json哈希的值并打印出交叉点。@JimB是的,我将json封送到这种格式,因为数据是任意的。@VladtheImpala您的评论和问题不匹配谢谢,关键是
reflect.TypeOf(value).Kind()==reflect.Map
@VladtheImpala注意:使用Go 1.5打印reflect.value()会更容易。看,你能指出应该如何使用它吗?当我使用
InspectStruct(myMap,1)
时,它会在映射值上给出错误
reflect.Value.NumField
@bat,应该这样使用,但它不是100%故障保存。我不得不时不时地禁用一些线路,以便在特定的有效负载下工作。