2017-02-10 45 views
0

我有以下代码来加倍切片。如何确定切片接口{}的元素类型?

func doubleSlice(s []int) []int { 
    t := make([]int, len(s), (cap(s) + 1) * 2) 
    for i := range s { 
    t[i] = s[i] 
    } 
    return t 
} 

我想使功能加倍任何类型的切片。我首先需要知道元素类型。

func showInterfaceItem(s interface{}) interface{} { 
    if reflect.TypeOf(s).Kind() != reflect.Slice { 
    fmt.Println("The interface is not a slice.") 
    return 
    } 

    var t interface{} 
    newLen := reflect.ValueOf(s).Len() 
    newCap := (cap(reflect.ValueOf(s).Cap()) + 1) * 2 
    t = make([]reflect.TypeOf(s), newLen, newCap) 

    return t 
} 

reflect.TypeOf(s)返回接口{类型},而不是元件的类型。我如何获得切片界面的元素类型?

+0

这不是完全清楚你已经尝试过?你在一个没有回归变量的函数中返回值? 'func showInterfaceItem(s interface {})({{here here}}){' – silvergasp

+0

我想实现自动检查元素类型。如果's'是'[] int','t'是'[] int'。如果's'是'[] float32','t'是'[] float32'。 – firelyu

+0

我想你误解了我的问题......你的函数不会编译。它正在返回一个值'return t',但是没有返回值是你的函数 – silvergasp

回答

1

您可以使用reflect.TypeOf(s).Elem() 获得片元素的类型。

package main 

import (
    "fmt" 
    "reflect" 
) 

func doubleSlice(s interface{}) interface{} { 
    if reflect.TypeOf(s).Kind() != reflect.Slice { 
     fmt.Println("The interface is not a slice.") 
     return nil 
    } 

    v := reflect.ValueOf(s) 
    newLen := v.Len() 
    newCap := (v.Cap() + 1) * 2 
    typ := reflect.TypeOf(s).Elem() 

    t := reflect.MakeSlice(reflect.SliceOf(typ), newLen, newCap) 
    reflect.Copy(t, v) 
    return t.Interface() 
} 

func main() { 
    xs := doubleSlice([]string{"foo", "bar"}).([]string) 
    fmt.Println("data =", xs, "len =", len(xs), "cap =", cap(xs)) 

    ys := doubleSlice([]int{3, 1, 4}).([]int) 
    fmt.Println("data =", ys, "len =", len(ys), "cap =", cap(ys)) 
} 

输出将是:

data = [foo bar] len = 2 cap = 6 
data = [3 1 4] len = 3 cap = 8 

检查它在:Go Playground

+0

'reflect.MakeSlice()'和'reflect.Sliceof()'是我需要的。与他们一起,我执行我的计划。 – firelyu

相关问题