为了账号安全,请及时绑定邮箱和手机立即绑定

Go中的可变参数泛型参数

Go中的可变参数泛型参数

Go
忽然笑 2021-05-05 17:33:06
假设我想使Go中的JavaScriptArray.splice函数等效于Slices。我有以下代码: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}此示例将起作用,但仅适用于type类型的参数int。我想使其通用,我知道我应该给可变参数elements指定类型interface{},但是如何从函数内部创建具有该接口类型的新切片呢?换句话说,如何根据函数第一行(在何处newslice创建)中的参数类型来动态指定切片的类型?
查看完整描述

2 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

相反,在围棋模仿的JavaScript(为什么???)我想建议由积木组成simmilar所需的操作SliceTricks

他们是:

  • 完全键入不可知论者(免费考虑“泛型”)。

  • 与从中打包或从中解包相比,速度可能要快得多[]interface{}


查看完整回答
反对 回复 2021-05-24
?
慕森卡

TA贡献1806条经验 获得超8个赞

使用反射

如果您真的想做一般性的事情,那么反射是最终的答案。有关 问题的详细信息,请参阅反射包中的MakeSlice文档。


您只需要检索传入切片的类型(使用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())

在这里运行。


使用 []interface{}

可以使用的另一种方法是[]interface{},它可以存储任何值,但是由于您完全省略了编译器类型检查,因此可能导致运行时出现混乱(这是一件坏事)。


这是[]interface{} 用作任意值存储的示例。这样,您就不需要知道拼接实现中的类型,只需拼接并[]interface{}用于新的切片即可。


这种方法的缺点是,您无法[]interface{}轻松地将某些切片转换为。您必须手动复制它,如之前的文章所述。


结论

无论使用哪个版本,都不会知道类型并手动将其转换回安全性。Go中没有这样的东西可以为您做到这一点。这意味着,您的代码中将具有以下类似内容来重新获得类型安全性:


x := []int{1,2,3,4}

y := splice(x, ...)

yn := []int(y)


查看完整回答
反对 回复 2021-05-24
  • 2 回答
  • 0 关注
  • 226 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信