无效操作:type interface 不支持索引
Posted
技术标签:
【中文标题】无效操作:type interface 不支持索引【英文标题】:invalid operation: type interface does not support indexing无效操作:type interface 不支持索引 【发布时间】:2018-05-24 15:58:09 【问题描述】:我是 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)
【问题讨论】:
这是一个不错的资源gobyexample.com/json @jeff 我正在使用界面,假设我不知道响应的结构。 @Jeff 它可以工作,但假设我必须解析嵌套元素,这个解决方案会很复杂。你有其他解决方案吗? 【参考方案1】:你也可以这样做:
var inputJson string = "..."
var decoded map[string]map[string]interface
json.Unmarshal([]byte(inputJson), &decoded)
test := decoded["data"]["type"]
fmt.Println(test)
// output: domains
【讨论】:
【参考方案2】:d
是interface
类型,所以你不能像d["data"]
那样索引它,你需要另一个类型断言:
test := d.(map[string]interface)["data"].(map[string]interface)["type"]
fmt.Println(test)
然后它将起作用。输出将是"domains"
。请参阅Go Playground 上的工作示例。
还请注意,如果您将d
声明为map[string]interface
类型,则可以省略第一个类型断言:
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)
输出是一样的。在Go Playground 上试试这个。
如果您需要多次执行这些和类似操作,您可能会发现我的 github.com/icza/dyno
库很有用(其主要目标是帮助处理动态对象)。
【讨论】:
给像我这样的新手的提示:要理解这段代码为什么有效,应该了解Decode
的工作原理,这与unmarshal
有关。 json.Unmarshal
文档解释了它如何存储数据。【参考方案3】:
你需要一些技巧来处理你的情况。 就像使用反射一样,您可以参考 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)
【讨论】:
这个问题与BSON或Mongo无关。如果你想在这种情况下引用一些使用反射的东西,你不妨阅读json
包的源代码,因为它实际上是相关的。
我推荐阅读bson.M,因为提问者在cmets中说,nested interface,我认为bson.M是decode nested interface的一个例子
嵌套的处理是简单的递归。 JSON 也可以。
我是新手,对 bson.M 很熟悉,很抱歉浪费您的时间。以上是关于无效操作:type interface 不支持索引的主要内容,如果未能解决你的问题,请参考以下文章
Go: 无效操作 - 类型 *map[key]value 不支持索引
[Amazon](500310) 无效操作:尚不支持此类IN/NOT IN查询;
无效的捆绑包。捆绑包 xxx 不支持最低操作系统版本 (2020)
Redshift 中的 DAU WAU MAU 错误:[Amazon](500310) 无效操作:由于内部错误,不支持此类关联子查询模式;