我在地图中有数据,我想按键索引地图以获取值。
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)
但是,我收到了相同的错误消息。我做错了什么?
答案 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())
}