获取无效操作:mymap [“title”](类型interface {}不支持索引)在尝试索引地图时

时间:2014-08-09 00:23:39

标签: map go

我在地图中有数据,我想按键索引地图以获取值。

mdi, err := page.Metadata()
fmt.Println(mdi["title"])

但是我不断收到错误消息invalid operation: mdi["title"] (type interface {} does not support indexing)。我很困惑,因为数据是一个地图,我应该能够索引它以获得值。如果类型不清楚,我还尝试将值转换为字符串:

title, ok := mdi["title"].(string)
checkOk(ok)
fmt.Println(title)

但是,我收到了相同的错误消息。我做错了什么?

3 个答案:

答案 0 :(得分:63)

这里的数据类型是关键。 mdi实际上不是地图,而是interface{},可以是任何东西 - 地图,字符串,整数。您需要先将其声明为具有预期键/值类型的地图,或者执行JSON and Go中概述的笨拙case开关。

mdi, err := page.Metadata()
md, ok := mdi.(map[string]interface{})
fmt.Println(md["title"])

答案 1 :(得分:0)

我不确定您是否可以控制page.Metadata的操作,但是如果您可以控制, 在这种情况下可以使用更好的方法。假设您的代码如下:

package main

import (
   "encoding/json"
   "log"
)

func Metadata() (interface{}, error) {
   y := []byte(`{"metadata": {"title": "Stack Overflow"}}`)
   var m map[string]interface{}
   e := json.Unmarshal(y, &m)
   if e != nil {
      return nil, e
   }
   return m["metadata"], nil
}

func main() {
   m, e := Metadata()
   if e != nil {
      log.Fatal(e)
   }
   s := m["title"]
   println(s == "Stack Overflow")
}

您将收到与您相同的错误。但是您可以将其更改为:

type Map map[string]interface{}

func (m Map) M(s string) Map {
   return m[s].(map[string]interface{})
}

func (m Map) S(s string) string {
   return m[s].(string)
}

func Metadata() (Map, error) {
   y := []byte(`{"metadata": {"title": "Stack Overflow"}}`)
   var m Map
   e := json.Unmarshal(y, &m)
   if e != nil {
      return nil, e
   }
   return m.M("metadata"), nil
}

func main() {
   m, e := Metadata()
   if e != nil {
      log.Fatal(e)
   }
   s := m.S("title")
   println(s == "Stack Overflow")
}

然后,每当需要索引时,只需根据以下情况调用适当的方法 关于您要返回的内容。您还可以根据需要添加切片 []interface{},以及我提出的其他方法,例如,如果您需要 返回整数。最后,如果您要检查Map是否包含密钥,则可以执行 这个:

if m["title"] != nil {
   s := m.S("title")
   println(s == "Stack Overflow")
}

答案 2 :(得分:-6)

您的page.Metadata可能会返回指针而不是值。以下代码就像魅力一样:

package main

import "fmt"

type SomeCustomType map[string]interface{}

func PageData() SomeCustomType {
    return SomeCustomType{"bar": "baz"}
}

func main() {
    fmt.Printf("%+v\n", PageData())
}