假设我们有一个基类型,从它派生出另一个类型
type baseType struct {
}
type derivedType struct {
baseType
}
如何将derivedType的切片转换为baseType?
derivedTypeSlice := []derivedType{}
func iTakeBaseSlice(baseSlice []baseType ) {
}
iTakeBaseSlice(???derivedTypeSlice)
@Gavin建议使用泛型
func iTakeBaseSlice[T baseType | derivedType](baseSlice []T) {
}
这种方法唯一的缺点是,函数必须知道将调用它的所有派生类型。这对于未导出的函数来说不是问题(最有可能的是未导出的函数知道在包中调用它的类型),但对于导出的函数来说是个问题。
我的想法是循环派生片并追加到基类型的新片中
derivedTypeSlice := []derivedType{}
baseTypeSlice := []baseTypeSlice{}
for _, derivedTypeElement := range derivedTGypeSlice {
baseTypeSlice = append(baseTypeSlice, derivedTypeElement.baseType)
}
iTakeBaseSlice(baseTypeSlice)
这种方法的缺点是性能和内存损失。因为派生切片将被复制到基本切片中,因此使内存使用量加倍。追加操作(如果派生的切片是常量大小,则可以避免)在性能方面代价高昂。
1条答案
按热度按时间jdzmm42g1#
结构嵌入不是子类化。一般来说,
[]baseType
和[]derivedType
是不可赋值的。处理这个问题的一种方法是使用接口。对于接口数组,每个值都可以有自己的类型。您可以编写接受接口的函数,并使用方法与项(或反射)交互。所以你的列表类型可以是
[]interface{...}
(其中...
是你需要的方法)接口是两个指针:一个类型指针和一个指向值的指针。您还可以考虑是否只使用值指针。通过这种方式,您将创建一个指向“基类型”的指针列表,并将其传递给希望采用基类型的函数。所以它是
[]*baseType
。根据列表的大小,创建新列表并填充它可能比您想象的要快。基准测试,并找出答案!