如何实现通用切片追加程序?

时间:2018-08-01 02:36:57

标签: generics go slice

我是go的新手。我正在尝试编写一个通用的“ appender”函数。这是一种简化,但是它是尝试创建一个干净的接口来处理某些列表的尝试。具体来说,我对由此产生的两个错误有疑问:

package main

type GenericFunc func() *interface{}
func Append(ints interface{}, f GenericFunc) {
    ints = append(ints, f())
}

func ReturnInt() *int {
    i := 1
    return &i
}

func main() {
    var ints []*int
    Append(ints, ReturnInt)
}

Playground

  

prog.go:5:18:追加的第一个参数必须为slice;有界面   {} prog.go:15:11:无法将ReturnInt(类型func()* int)用作类型   将GenericFunc用作附加参数

  1. 为什么ReturnInt不能为GenericFunc类型?如果这不起作用,我根本不了解interface{}怎么可以与函数一起使用..可以吗?
  2. 如何接受“通用”切片并使用反射将其追加?这将涉及检查GenericFunc返回的切片类型是否相同,但是之后应该可以追加。

1 个答案:

答案 0 :(得分:2)

类型func() *interface{}(GenericFunc的类型)和(type func() *int)(ReturnInt的类型)是不同的类型。一个返回*interface{}。另一个返回*int。这些类型不能相互分配。

使用此函数通常将函数的结果附加到切片:

func Append(sp interface{}, f interface{}) {
    s := reflect.ValueOf(sp).Elem()
    s.Set(reflect.Append(s, reflect.ValueOf(f).Call(nil)[0]))
}

这样称呼它:

var ints []*int
Append(&ints, ReturnInt)

如果参数不是切片的指针,或者该函数未返回可分配给切片元素的值,则该函数将出现紧急情况。

playground example