type interface {}不支持golang中的索引

Ken*_*tov 3 arrays indexing dictionary go

我有这样的地图:

Map := make(map[string]interface{})
Run Code Online (Sandbox Code Playgroud)

该映射应该包含从字符串到对象数组的映射.数组可以是不同的类型,如[]Users[]Hosts.我填充了这个数组:

TopologyMap["Users"] = Users_Array
TopologyMap["Hosts"] = Hosts_Array
Run Code Online (Sandbox Code Playgroud)

但是当我试图从中获取元素时:

Map["Users"][0]
Run Code Online (Sandbox Code Playgroud)

它给出了一个错误: (type interface {} does not support indexing)

我怎么能克服它?

Vad*_*yus 6

您必须将接口{}显式转换为已执行类型的切片才能实现它.像这样的东西 https://play.golang.org/p/yZmniZwFar


Guj*_*ana 6

首先要注意的是interface{}可以容纳任何数据类型,包括functionstruct[]struct。由于错误给你:

(type interface {} 不支持索引)

这意味着它没有slice或没有array值。因为index在这种情况下你直接调用is0到 aninterface{}并且你假设 the Map["Users"]is 一个数组。但事实并非如此。这是 Go 的一大优点,它是静态类型,这意味着所有数据类型都在编译时进行检查。

如果你想避免这样的解析错误:

恐慌:接口转换:接口{}是[]main.User,而不是[]main.Host

为了避免在将其解析为另一种类型时出现该错误Map["user"].([]User),以防万一另一种数据类型传递给interface{}以下代码片段:

u, ok := myMap["user"].([]User)
if ok {
    log.Printf("value = %+v\n", u)
}
Run Code Online (Sandbox Code Playgroud)

上面的代码很简单,你可以用它来检查接口是否与你正在解析的类型匹配。

如果您想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])

}
Run Code Online (Sandbox Code Playgroud)

在您知道 的值是什么之后,interface{}您可以自信地解析它在这种情况下是 user 切片的特定数据类型[]User。并不是说main有一个包名称,您可以将其更改为您的名称。

  • 没有理由在这里进行反思。使用类型断言的二值形式来避免恐慌: u, ok := myMap["user"].([]User) (2认同)