【问题标题】:Unable to assert type `[]string` from `[]interface{}`无法从 `[]interface{}` 断言类型 `[]string`
【发布时间】:2014-05-10 13:53:15
【问题描述】:

我正在尝试处理从 mongodb (mgo) 检索到的一些数据。

不幸的是,我无法为字符串列表断言正确的类型。 我正在处理的功能如下:

func generate_version_histogram(userStats []interface{}) map[string]int {
    var histogram map[string]int
    for _, _u := range userStats {
        u := _u.(bson.M)
        for _, version := range (u["v"]).([]string) {
            if _, alreadyhere := histogram[version]; alreadyhere {
                histogram[version] += 1
            } else {
                histogram[version] = 1
            }
        }
    }
    return histogram
}

不幸的是,我遇到了以下运行时恐慌:

interface conversion: interface is []interface {}, not []string

知道为什么会这样吗?如何检索这些字符串?

【问题讨论】:

  • 尝试断言切片的每个成员而不是整个切片。

标签: mongodb casting go type-conversion mgo


【解决方案1】:

这是 Go 的常见错误。

原因如下:在Go中[]interface{}不是接口,它是一个切片类型,其元素都是interface{}类型。

因为每个元素都是一个interface{},而不是比如说intFoo,所以每个元素会占用更多的内存(interface{}需要存储底层类型,以及包含的值) .因此,无法将[]interface 值直接转换为[]string[]T 值。

那么如何将[]interface{} 转换为[]string

解决方案非常简单——转换每个元素。

package main

import "fmt"

func main() {
    foo := []interface{}{"a", "b", "c"}

    // we want to convert foo to a []string
    out := []string{}

    for _, v := range foo {
        // using a type assertion, convert v to a string
        out = append(out, v.(string))
    }

    fmt.Println(out)
}

可运行示例here.

【讨论】:

    【解决方案2】:

    []interface{} 永远不会是[]string。切片有一个后备数组,这些元素必须具有一定的大小。这可能会或可能不会完全正确,具体取决于实现细节,但[]interface{} 的每个元素都将包含interface{}。如果所有这些interface{} 都是“真正的”字符串,那么它们将不是字符串本身,而是字符串的包装器或指向它的指针。因此,您必须自己转换 []interface{} 的每个单独元素。

    stringSlice := make([]string, len(u["v"]))
    for i,raw := range u["v"] {
        str,ok := raw.(string)
        if !ok {
            // Something is wrong, not a string like we expected
        }
        stringSlice[i] = str
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-02
      • 1970-01-01
      • 2017-07-31
      • 2017-11-27
      • 2011-10-26
      • 1970-01-01
      • 2021-11-24
      • 2012-12-07
      • 2021-12-16
      相关资源
      最近更新 更多