Go泛型-将项目存储在具有不同约束的切片中?

2ledvvac  于 2023-06-19  发布在  Go
关注(0)|答案(1)|浏览(134)

我正在做一个小的副业项目,我想在Go中有一个切片,带有不同类型参数的任意数量的元素。
有可能吗?
我尝试了以下方法:

func main() {
    fCallOne := functionCall[bool]{
        returnValue: false,
    }

    fCallTwo := functionCall[int]{
        returnValue: 0,
    }

    fCalls := make([]functionCall[any], 10)
    fCalls = append(fCalls, fCallOne)
}

type functionCall[T any] struct {
    returnValue T
}

但这不管用。我希望能够做一些事情,比如:
在一个切片中存储一定数量的元素(所有元素共享相同的API)。检索切片中给定索引的值(不进行任何类型转换)。
什么是最好的方法来完成这样的事情?
目前,我已经完成了以下工作,但这也不起作用:

func main() {
    container := make([]tuple[any], 0)
    elem := T1[bool]{
        V1: false,
    }

    container = append(container, elem)
}

type tuple[T any] interface {
    getValue() T
}

// T1 is a tuple type holding 1 generic values.
type T1[Ty1 any] struct {
    V1 Ty1
}

func (t T1[Ty1]) getValue() Ty1 {
    return t.V1
}
njthzxwz

njthzxwz1#

在第一次尝试中,any在以下行的上下文中:

fCalls := make([]functionCall[any], 10)
                              ^^^

不是 constraint,而是泛型类型functionCalltype argument。在这里,您正在创建一个切片,其元素的类型为functionCall[any]。要附加到该切片的fCallOne值的类型是functionCall[bool]而不是functionCall[any],这就是为什么下面的行无法编译的原因:

fCalls = append(fCalls, fCallOne)

但是,由于您可以为any接口分配任何值,因此可以将false0分配给any字段:

fCallAny1 := functionCall[any] {
    returnValue: false,
}

fCallAny2 := functionCall[any] {
    returnValue: 0,
}

fCalls := make([]functionCall[any], 10)
fCalls = append(fCalls, fCallAny1, fCallAny2)

我希望能够做一些事情,比如:在一个切片中存储一定数量的元素(所有元素共享相同的API)。
如果所有元素共享相同的API,例如:

type foo int
type bar string

func (foo) doSomething(){}
func (bar) doSomething(){}

然后,您可以定义一个表示共享API的接口:

type sharedAPI interface {
    doSomething()
}

最后,您可以创建一个sharedAPI s的切片,并附加满足此接口的值:

container := make([]sharedAPI, 2)
container = append(container, foo(0), bar("hi"))

您将可以访问切片的每个元素上的共享API:

container[0].doSomething()
container[1].doSomething()

检索切片中给定索引的值(不进行任何类型转换)。
这是不可能的,因为部分静态类型信息丢失了:你不再有foobar类型的元素,而只有sharedAPI类型的元素。此外,所有slice元素必须具有相同的静态类型(均为sharedAPI)。必须使用类型Assert或类型开关来利用接口sharedAPI包含的动态类型信息。

相关问题