问题
I'm new to the golang and I have problem while reading the nested JSON response.
var d interface{}
json.NewDecoder(response.Body).Decode(&d)
test :=d["data"].(map[string]interface{})["type"]
response.Body
looks like this
{
"links": {
"self": "/domains/test.one"
},
"data": {
"type": "domains",
"id": "test.one",
"attributes": {
"product": " Website",
"package": "Professional",
"created_at": "2016-08-19T11:37:01Z"
}
}
}
The Error I'm getting is this:
invalid operation: d["data"] (type interface {} does not support indexing)
回答1:
d
is of type interface{}
, so you cannot index it like d["data"]
, you need another type assertion:
test := d.(map[string]interface{})["data"].(map[string]interface{})["type"]
fmt.Println(test)
Then it will work. Output will be "domains"
. See a working example on the Go Playground.
Also note that if you declare d
to be of type map[string]interface{}
, you can spare the first type assertion:
var d map[string]interface{}
if err := json.NewDecoder(response.Body).Decode(&d); err != nil {
panic(err)
}
test := d["data"].(map[string]interface{})["type"]
fmt.Println(test)
Output is the same. Try this one on the Go Playground.
If you need to do these and similar operations many times, you may find my github.com/icza/dyno library useful (whose primary goal is to aid working with dynamic objects).
回答2:
You need some tricks to handle your situation.
Like using reflect and you may ref Marshall&&UnMarshall code about bson.M in golang mongo driver mgo
code sample using reflect decode nested as following:
package main
import (
"encoding/json"
"fmt"
"reflect"
)
func main() {
keys := []string{"hello", "world", "dude", "kind", "cool"}
a := make(map[string]interface{})
a[keys[4]] = "perfect"
b := make(map[string]interface{})
b[keys[3]] = a
c := make(map[string]interface{})
c[keys[2]] = b
d := make(map[string]interface{})
d[keys[1]] = c
e := make(map[string]interface{})
e[keys[0]] = d
fmt.Println(e)
if buf, err := json.Marshal(e); nil == err {
dd := make(map[string]interface{})
err = json.Unmarshal(buf, &dd)
if nil != err {
fmt.Println("failed", err)
}
for k, v := range dd {
travel(dd, k, v)
}
fmt.Println(dd)
} else {
fmt.Println("failed marshal")
}
}
func travel(dd map[string]interface{}, key string, value interface{}) {
vv := reflect.ValueOf(value)
switch vv.Kind() {
case reflect.Map:
m := value.(map[string]interface{})
dd[key] = m
for k, v := range m {
travel(m, k, v)
}
case reflect.String:
dd[key] = value.(string)
}
}
来源:https://stackoverflow.com/questions/47747663/invalid-operation-type-interface-does-not-support-indexing