invalid operation: type interface {} does not support indexing

白昼怎懂夜的黑 提交于 2019-12-13 20:26:46

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!