如何使用Go unmarshal解析复杂的JSON?

井:

go标准包中,encoding / json公开json.Unmarshal了解析JSON的函数。

可以解封预定义的JSON字符串struct,或使用interface{}并迭代结果以获取意外的JSON数据结构。

也就是说,我无法正确解析复杂的JSON。有人可以告诉我如何实现吗?

 {
     "k1" : "v1", 
     "k2" : "v2", 
     "k3" : 10, 
     "result" : [
                 [
                 ["v4", v5, {"k11" : "v11", "k22" : "v22"}]
                 , ... , 
                 ["v4", v5, {"k33" : "v33", "k44" : "v44"}
                 ]
                 ], 
                 "v3"
                ] 
}
约翰·维克斯特伦(JohanWikström):

JSON和Go引用

在不知道此数据的结构的情况下,我们可以使用Unmarshal将其解码为interface {}值:

b := []byte(`{
   "k1" : "v1", 
   "k3" : 10,
   result:["v4",12.3,{"k11" : "v11", "k22" : "v22"}]
}`)
var f interface{}
err := json.Unmarshal(b, &f)

此时,f中的Go值将是一个映射,其键为字符串,并且其值本身存储为空接口值:

f = map[string]interface{}{
    "k1": "v1",
    "k3":  10,
    "result": []interface{}{
       "v4",
       12.3,
       map[string]interface{}{
           "k11":"v11",
           "k22":"v22",
       },
    },
}

要访问此数据,我们可以使用类型断言来访问f底层的map [string] interface {}:

m := f.(map[string]interface{})

然后,我们可以使用range语句遍历地图,并使用类型开关将其值作为其具体类型来访问:

for k, v := range m {
    switch vv := v.(type) {
    case string:
        fmt.Println(k, "is string", vv)
    case int:
        fmt.Println(k, "is int", vv)
    case []interface{}:
        fmt.Println(k, "is an array:")
        for i, u := range vv {
            fmt.Println(i, u)
        }
    default:
        fmt.Println(k, "is of a type I don't know how to handle")
    }
}

这样,您可以使用未知的JSON数据,同时仍然享有类型安全的好处。

可以在原始文章中找到有关Go和JSON的更多信息。我稍微更改了代码片段,使其与问题中的JSON更加相似。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TOP 榜单

热门标签

归档