类型转换接口切片 [英] Type converting slices of interfaces

查看:34
本文介绍了类型转换接口切片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇为什么 Go 不会隐式转换 []T[]interface{} 而它会隐式转换 T接口{}.我遗漏了有关此转换的重要内容吗?

I'm curious why Go does't implicitly convert []T to []interface{} when it will implicitly convert T to interface{}. Is there something non-trivial about this conversion that I'm missing?

示例:

func foo([]interface{}) { /* do something */ }

func main() {
    var a []string = []string{"hello", "world"}
    foo(a)
}

go build 抱怨

不能在函数参数中使用 (type []string) 作为 []interface {} 类型

cannot use a (type []string) as type []interface {} in function argument

如果我尝试明确地这样做,同样的事情:b := []interface{}(a) 抱怨

And if I try to do it explicitly, same thing: b := []interface{}(a) complains

无法将 (type []string) 转换为 type []interface {}

cannot convert a (type []string) to type []interface {}

所以每次我需要做这个转换(这似乎出现了很多),我一直在做这样的事情:

So every time I need to do this conversion (which seems to come up a lot), I've been doing something like this:

b = make([]interface{}, len(a), len(a))
for i := range a {
    b[i] = a[i]
}

有没有更好的方法来做到这一点,或者标准库函数来帮助这些转换?每次我想调用一个可以接受例如列表的函数时,多写 4 行代码似乎有点傻.整数或字符串.

Is there a better way to do this, or standard library functions to help with these conversions? It seems kind of silly to write 4 extra lines of code every time I want to call a function that can take a list of e.g. ints or strings.

推荐答案

在 Go 中,有一个通用规则,即语法不应隐藏复杂/昂贵的操作.将 string 转换为 interface{} 在 O(1) 时间内完成.将 []string 转换为 interface{} 也是在 O(1) 时间内完成的,因为切片仍然是一个值.但是,将 []string 转换为 []interface{} 是 O(n) 时间,因为切片的每个元素都必须转换为 interface{}.

In Go, there is a general rule that syntax should not hide complex/costly operations. Converting a string to an interface{} is done in O(1) time. Converting a []string to an interface{} is also done in O(1) time since a slice is still one value. However, converting a []string to an []interface{} is O(n) time because each element of the slice must be converted to an interface{}.

此规则的一个例外是转换字符串.将 string 转换为 []byte[]rune 时,Go 执行 O(n) 工作,即使转换是";语法".

The one exception to this rule is converting strings. When converting a string to and from a []byte or a []rune, Go does O(n) work even though conversions are "syntax".

没有标准库函数可以为您进行这种转换.你可以用reflect做一个,但它会比三行选项慢.

There is no standard library function that will do this conversion for you. You could make one with reflect, but it would be slower than the three line option.

反射示例:

func InterfaceSlice(slice interface{}) []interface{} {
    s := reflect.ValueOf(slice)
    if s.Kind() != reflect.Slice {
        panic("InterfaceSlice() given a non-slice type")
    }

    // Keep the distinction between nil and empty slice input
    if s.IsNil() {
        return nil
    }

    ret := make([]interface{}, s.Len())

    for i:=0; i<s.Len(); i++ {
        ret[i] = s.Index(i).Interface()
    }

    return ret
}

不过,您最好的选择只是使用您在问题中提供的代码行:

Your best option though is just to use the lines of code you gave in your question:

b := make([]interface{}, len(a))
for i := range a {
    b[i] = a[i]
}

这篇关于类型转换接口切片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆