程序go 2012-10-05 20:48 采纳率: 100%
浏览 258
已采纳

在 go 中键入转换接口的片

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.

转载于:https://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go

  • 写回答

4条回答 默认 最新

  • 北城已荒凉 2012-10-05 22:16
    关注

    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]
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应