How to access the fields of the interface in json decoding?
I have a json document and I am using a client that decodes the document in an interface (instead of a structure) as shown below:
var jsonR interface{}
err = json.Unmarshal(res, &jsonR)
How can I access the fields of the interface? I read go doc and blog , but my head still can't get it. Their example shows that you can decode json in the frontend, but does not explain how its fields can be used.
I tried using a range loop but it seems like the story ends when I reach the map interface [string]. The fields 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)
}
}
source to share
The meaning inside the interface depends on the json structure you are parsing. If you have a json-dictionary, dynamic type jsonR
is: 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"])
}
source to share
Parsing this type can be very difficult. The default parsing type is map[string]interface{}
. The problem comes when you have another complex data structure inside the main json (like another list or object). The best way to decode json is by defining a structure to store the data. Not only will the values be of the correct type, but you can retrieve the specific data that you really need.
Your structure might 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 structure regular operations to access your data like this:
value := data.Topfield
json, which contains more complex data, can also be decoded by easyli. Perhaps you have a list in your data somewhere, you can use the following structure 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 the list, but also parse objects with fields.
source to share