无效操作:type interface {}不支持索引

时间:2017-12-11 06:42:49

标签: json dictionary go unmarshalling type-assertion

我是Golang的新手,在阅读嵌套的JSON响应时遇到了问题。

var d interface{}
json.NewDecoder(response.Body).Decode(&d)
test :=d["data"].(map[string]interface{})["type"]

response.Body看起来像这样

{
    "links": {
      "self": "/domains/test.one"
    },
    "data": {
        "type": "domains",
        "id": "test.one",
        "attributes": {
            "product": " Website",
            "package": "Professional",
            "created_at": "2016-08-19T11:37:01Z"
        }
    }
}

我得到的错误是:

invalid operation: d["data"] (type interface {} does not support indexing)

3 个答案:

答案 0 :(得分:4)

public function __construct() { $this->middleware('admin'); } 的类型为 public function __construct() { $this->middleware('agent'); } ,因此您无法将其编入索引,如d,您需要其他类型的断言:

interface{}

然后它会起作用。输出将为d["data"]。请参阅Go Playground上的工作示例。

另请注意,如果您将test := d.(map[string]interface{})["data"].(map[string]interface{})["type"] fmt.Println(test) 声明为"domains"类型,则可以省略第一种类型的断言:

d

输出是一样的。在Go Playground上试试这个。

如果您需要多次执行这些操作和类似操作,您可能会发现我的github.com/icza/dyno库很有用(其主要目标是帮助处理动态对象)。

答案 1 :(得分:0)

你需要一些技巧来处理你的情况 就像使用反射一样,你可以在golang mongo driver mgo中找到关于bson.M的Marshall&&& UnMarshall代码

使用反射解码的

代码示例嵌套如下:

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

答案 2 :(得分:0)

您也可以这样做:

var inputJson string = "..."

var decoded map[string]map[string]interface{}

json.Unmarshal([]byte(inputJson), &decoded)

test := decoded["data"]["type"]

fmt.Println(test)
// output: domains