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

I have a json document and I'm using a client which decodes the document in an interface (instead of struct) as below:

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

How can I access the interface fields? I've read the go doc and blog but my head still can't get it. Their example seem to show only that you can decode the json in an interface but doesn't explain how its fields can be used.

I've tried to use a range loop but it seems the story ends when I reach a map[string]interface. The fields that I need seem to be in the interface.

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

    }

}

The value inside the interface depends on the json structure you're parsing. If you have a json dictionary, the dynamic type of jsonR will be: map[string]interface{}.

Here's an example.

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

Parsing json like this can be very difficult. The default type of a parse is map[string]interface{}. The Problem arises when you have another complex data structure within the main json(like another list or object). The best way to go about decoding json is defining a struct to hold data. Not only will the values be of the correct type but you can extract the specific data you actually care about.

Your struct can look like this:

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

which can be decoded like this:

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

now you can use regular struct operations to access your data like this:

value := data.Topfield

json which contains more complex data can also be easyli decoded. Perhaps you have a list in your data somewhere, you can use a struct like the following to extract it:

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"`
}

such a structure can not only parse list but also parse objects withing fields.