如何访问json解码的接口字段?

时间:2014-05-10 04:47:29

标签: json go

我有一个json文档,我正在使用一个客户端,它在一个接口(而不是struct)中解码文档,如下所示:

var jsonR interface{}
err = json.Unmarshal(res, &jsonR)

如何访问界面字段?我已经阅读了go doc和blog但我的头脑仍然无法得到它。他们的例子似乎只显示你可以解码界面中的json,但没有解释如何使用它的字段。

我尝试使用范围循环,但是当我到达地图[string]界面时,故事似乎就结束了。我需要的字段似乎在界面中。

for k, v := range jsonR {
    if k == "topfield" {
        fmt.Printf("k  is %v, v is %v", k, v)

    }

}

2 个答案:

答案 0 :(得分:0)

接口内的值取决于您要解析的json结构。如果您有json字典,则动态类型jsonR将为:map[string]interface{}

以下是一个例子。

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

func main() {
    a := []byte(`{"topfield": 123}`)
    var v interface{}
    if err := json.Unmarshal(a, &v); err != nil {
        log.Fatalf("unmarshal failed: %s", err)
    }
    fmt.Printf("value is %v", v.(map[string]interface{})["topfield"])
}

答案 1 :(得分:0)

像这样解析json可能非常困难。解析的默认类型是map[string]interface{}。当您在主json(如另一个列表或对象)中有另一个复杂的数据结构时,会出现问题。解码json的最佳方法是定义一个用于保存数据的结构。这些值不仅具有正确的类型,而且您可以提取您真正关心的特定数据。

您的结构可能如下所示:

type Top struct {
    Topfield int `json:"topfield"`
}

可以像这样解码:

a := []byte(`{"topfield": 123}`)
var data Top
json.Unmarshal(a, &data) //parse the json into data

现在您可以使用常规结构操作来访问您的数据,如下所示:

value := data.Topfield

包含更复杂数据的json也可以进行解码。也许你的数据中有一个列表,你可以使用如下的结构来提取它:

type Data struct {
    States []string `json:"states"`
    PopulationData []Country `json:"popdata"`
}

type Country struct {
    Id int `json:"id"`
    LastCensusPop int `json:"lcensuspopulation"`
    Gdp  float64 `json:"gdp"`
}

这样的结构不仅可以解析列表,还可以解析带有字段的对象。