我有这样的地图:
Map := make(map[string]interface{})
此映射应包含从字符串到对象数组的映射。数组可以是不同类型,例如[]Users
或[]Hosts
。我填充了这个数组:
TopologyMap["Users"] = Users_Array
TopologyMap["Hosts"] = Hosts_Array
但是当我试图从中获取元素时:
Map["Users"][0]
它给出了一个错误:
(type interface {} does not support indexing)
我怎样才能克服它?
答案 0 :(得分:6)
您必须将接口{}显式转换为预期类型的切片才能实现它。像这样的东西 https://play.golang.org/p/yZmniZwFar
答案 1 :(得分:3)
首先要注意的是interface{}
可以包含任何数据类型,包括function
和struct
或[]struct
。由于错误给你:
(type interface {}不支持索引)
这意味着它没有slice
或没有array
值。因为您在这种情况下直接调用index
0
为interface{}
,并且您认为Map["Users"]
是一个数组。但事实并非如此。这是Go的一个非常好的事情,它是静态类型,这意味着在编译时检查所有数据类型。
如果你想避免像这样的解析错误:
恐慌:界面转换:interface {}是[] main.User,不是 [] main.Host
为了避免在将其解析为Map["user"].([]User)
之类的其他类型时出现错误,以防其他数据类型传递给interface{}
,请考虑下面的代码段:
u, ok := myMap["user"].([]User)
if ok {
log.Printf("value = %+v\n", u)
}
上面的代码很简单,您可以使用它来检查接口是否与您要解析的类型匹配。
如果您希望在运行时将值更通用地传递给interface{}
,可以先使用reflect.TypeOf()
进行检查,请考虑以下代码:
switch reflect.TypeOf(myMap["user"]).String() {
case "[]main.User":
log.Println("map = ", "slice of user")
logger.Debug("map = ", myMap["user"].([]User)[0])
case "[]main.Host":
log.Println("map = ", "slice of host")
logger.Debug("map = ", myMap["user"].([]Host)[0])
}
在您知道interface{}
的值之后,您可以自信地将其解析为您的特定数据类型(在此案例中为用户[]User
切片。并非main
有一个包名称,您可以将其更改为您的。