Go中的变量泛型参数
假设我想使函数在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 <
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代码,并首先使其工作,而不是立即使其习惯化。这就是为什么我要研究模拟拼接。