Go中的变量泛型参数

Go中的变量泛型参数,go,slice,polyvariadic,Go,Slice,Polyvariadic,假设我想使函数在Go中等效,用于切片。我有以下代码: func splice(slice []int, index, amount int, elements ...int) []int { newslice := make([]int, 0) for i := 0; i < index; i++ { newslice = append(newslice, slice[i]) } for i := index + amount; i <

假设我想使函数在Go中等效,用于切片。我有以下代码:

func splice(slice []int, index, amount int, elements ...int) []int {
    newslice := make([]int, 0)
    for i := 0; i < index; i++ {
        newslice = append(newslice, slice[i])
    }
    for i := index + amount; i < len(slice); i++ {
        newslice = append(newslice, slice[i])
    }
    for _, el := range elements {
        newslice = append(newslice, el)
    }
    return newslice
}
func拼接(切片[]整型,索引,金额整型,元素…整型)[]整型{
newslice:=make([]int,0)
对于i:=0;i
此示例将起作用,但仅适用于类型为
int
的参数。我想让它变得通用,我知道我应该给变量参数
元素
类型
接口{}
,但是我如何从函数内部创建一个具有该接口类型的新切片呢


换句话说,我如何根据函数第一行中的参数类型动态地指定切片的类型,其中创建了
newslice

而不是在Go中模拟JavaScript(为什么?),我建议从

它们是:

  • 完全类型不可知(免费考虑“泛型”)
  • 与在
    []接口{}
    中打包/解包相比,可能要快得多
使用反射 如果你真的想做一般的事情,反射是最终的答案。 见 在反射包中查看有关问题的详细信息

您只需要检索传入切片的类型(使用
TypeOf(…)
) 并正确应用
MakeSlice

使用反射创建切片的示例:

y := []int{1,2,3}
t := reflect.TypeOf(y)

slice := reflect.MakeSlice(t, 0, 10)
slice = reflect.Append(slice, reflect.ValueOf(2))

fmt.Println(slice.Interface())

使用
[]接口{}
使用的另一种方法是
[]接口{}
,它可以存储任何值 但如果完全忽略编译器类型检查,可能会导致运行时恐慌 (这是一件坏事)

是使用
[]接口{}
作为任意值的存储。有了这个,你不需要知道输入的类型 在拼接实现中,只需拼接并使用
[]接口{}
进行新切片

此方法有一个缺点,即您无法轻松地将某些切片转换为
[]接口{}
。如前所述,您必须手动复制它

结论 无论您使用哪种版本,如果没有安全保护,您将永远无法返回类型 了解类型并手动将其转换回。围棋里没有这种东西 这对你有好处。也就是说,你会有这样的东西 在恢复类型安全的代码中:

x := []int{1,2,3,4}
y := splice(x, ...)
yn := []int(y)

这个链接非常有用,谢谢!我正在移植一些JavaScript代码,并首先使其工作,而不是立即使其习惯化。这就是为什么我要研究模拟拼接。