猿问

将类型(int、float 等)转换为 `T` [go1.18]

场景:

支持泛型的 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在这种情况下)转换为泛型T? 错误:

cannot use i (variable of type int) as type T in argument to append


jeck猫
浏览 106回答 2
2回答

30秒到达战场

您可以像往常一样将值转换为参数类型。从提案类型转换:在具有两个类型参数From和的函数中,如果From 约束的类型集中的所有类型都可以转换为 To 约束的类型集中的所有类型,则 type 的值可以转换为 type 的值To。FromTo在这种情况下,您实际上并没有 aFrom因为它是切片索引int;目标类型将是T(即使这可能不是您想要的,请参阅下面的原因)。当然int可以转换为T' 类型集,因为它仅包括数字类型(尽管在or 的情况下会截断或丢失精度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}游乐场:https ://gotipplay.golang.org/p/EykXppG2qJa

哈士奇WWW

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}
随时随地看视频慕课网APP

相关分类

Go
我要回答