在go中键入转换接口片 [英] Type converting slices of interfaces in go

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

问题描述

我很好奇,为什么go不会隐式转换 [] T [] interface {} 它会隐式地将 T 转换为 interface {} 。这种转换有什么不重要的东西,我错过了吗?



示例:

  func foo([] interface {}) {/ *做点什么* /} 

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

go build 抱怨


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

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


$ b


无法将[type]字符串转换为[] interface {}


< blockquote>

因此,每次我需要做这种转换(似乎有很多),我一直在做这样的事情:

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

有没有更好的方法来做到这一点或标准库函数来帮助进行这些转换NS?每次我想调用一个函数时,写出4行额外的代码看起来很愚蠢。 ints或strings。

解决方案

在Go中,有一条通用规则,语法不应该隐藏复杂/昂贵的操作。在O(1)时间内完成字符串界面{} 的转换。将一个 []字符串转换为界面{} 也是在O(1)一个值。但是,将一个 []字符串转换为 [] interface {} 是O(n)时间,因为切片必须转换为接口{}



这个规则的一个例外是转换字符串。将字符串转换为 []字节 []符文,即使转换是语法,Go也会工作。



没有标准库函数可以为您执行此转换。



使用反射的示例:

  func InterfaceSlice(slice interface {})[] interface {} {
s:= reflect.ValueOf(slice)
如果s.Kind()!= reflect .Slice {
panic(给出非片类型的InterfaceSlice())
}
$ b $ ret:= make([] interface {},s.Len() )

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

return ret
}


你最好的选择就是使用你在你的问题中给出的代码行:

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


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?

Example:

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

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

go build complains

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

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

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]
}

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.

解决方案

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{}.

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".

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.

Example with reflection:

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

    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]
}

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

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