场景
Go 1.18支持泛型
问题
无法将数字转换为泛型。
解释
我正在尝试移植我的general purpose库以支持泛型。我在处理数字转换错误。
我定义了一个包含所有数字类型的包,如下所示:
package types
type Number interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64
}我没有什么特别的问题要处理仿制药。我唯一不明白的是:
如何将定义的类型(如int)转换为泛型?
让我们假设以下示例:
// FindIndexValue is delegated to retrieve the index of the given value into the input array.
func FindIndexValue[T types.Number](array []T, value T) []T {
var indexs []T
for i := range array {
if array[i] == value {
indexs = append(indexs, i)
}
}
return indexs
}在上面的片段中,错误位于行中:
...
for i := range array {
...
}这是因为range内置迭代数组并返回给定位置的索引(int)。
问题是:
如何将定义的类型(__int (在本例中)转换为通用错误:
cannot use i (variable of type int) as type T in argument to append
发布于 2021-12-08 11:56:10
按照通常的做法,将值转换为参数类型。
来自类型转换的提案
在具有两个类型参数
From和To的函数中,如果可以将From约束类型集中的所有类型转换为To's约束类型集中的所有类型,则可以将From类型的值转换为To类型集的值。
在这种情况下,您实际上没有一个From,因为它是片索引int;目标类型将是T (尽管这可能不是您想要的,请参见下面的原因)。当然,int可以转换为T的类型集,因为它只包括数值类型(尽管在int8或float64的情况下使用截断或精度损失!)
indexs = append(indexs, T(i))但是,您的程序将索引的片段声明为[]T,这意味着实例化您的泛型函数如下:
is := FindIndexValue([]float64{1,5,7,9}, float64(9))将产生[]float64类型的结果。因为返回的值是片索引,而这些索引总是int,所以这没有多大意义。
最好是返回简单的[]int
func FindIndexValue[T Number](array []T, value T) []int {
var indices []int
for i := range array {
// match on the generically typed slice item
if array[i] == value {
// store slice indices as ints
indices = append(indexs, i)
}
}
return indices
}发布于 2021-12-08 11:46:23
索引始终是整数类型(int),而不管片的元素类型如何。因此,结果类型应该是[]int。
你为什么希望它是[]T呢?如果T是uint8,并且传递的切片包含超过256个元素,则甚至无法返回适当的索引。
func FindIndexValue[T types.Number](array []T, value T) []int {
var indices []int
for i, v := range array {
if v == value {
indices = append(indices, i)
}
}
return indices
}https://stackoverflow.com/questions/70274394
复制相似问题