登录
首页 >  Golang >  Go问答

Golang 中的通用类型转换

来源:stackoverflow

时间:2024-03-13 18:03:28 281浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《Golang 中的通用类型转换》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

问题内容

我厌倦了编写像 []int32 -> []int64 这样的手动切片转换,因为在很多情况下您需要将切片与其他类型一起使用。 所以我尝试为此编写一个通用函数:

func convertslice[t1 any, t2 any](t1 []t1) []t2 {
    t2 := make([]t2, len(t1))
    for i := range t1 {
        t2[i] = t2(t1[i])
    }
    return t2
}

并且想像这样使用它

a := []int{1, 2, 3, 4, 5}
var b []int64 = convertslice[int, int64](a)

但我无法编译它,编译器说 ./prog.go:8:14: 无法将 t1[i] (受任何约束的 t1 类型变量)转换为 t2 类型

那么,我该如何解决这个问题?

实例:https://go.dev/play/p/yyolfjyt4mq

当然,我可以为每个基本类型编写单独的函数,例如:

func convertNumericSlice[T1, T2 constraints.Integer | constraints.Float](t1 []T1) []T2 {}
func convertStringSlice[T1, T2 ~string](t1 []T1) []T2 {}

但这看起来根本不像很酷的通用方式。


正确答案


无法转换具有任意约束的类型参数。规范提到(转换):

[...] 如果满足以下条件之一,x 也可以转换为类型 t:

  • v 和 t 都是类型参数,v 类型集中的每种类型的值都可以转换为 t 类型集中的每种类型

如果 t1t2 均受 any 约束,则这两个类型集实际上都包含任何可能的类型。

即使 convertslice 函数的特定实例可能有效,编译器也无法静态证明转换 t2(t1) 始终有效。理论上,您可以实例化 convertslice[string, chan func()] ,然后字符串显然无法转换为函数通道。

编写包罗万象的函数的唯一方法是使用反射和 canconvert a> 方法,但您需要决定如何处理 canconvert 返回 false 的情况。恐慌?返回零值?

如果您选择使用泛型,您就已经做出了类型安全的选择,因此引入反射似乎是违反直觉的。对于泛型,您必须为每组可转换基础类型编写函数。主要特殊情况有:

数字:

type number interface {
    constraints.integer | constraints.float
}

convertnumbers[t1, t2 number](t1 []t1) []t2 {}

字符串 - 它是字节切片和符文切片的特殊情况,但字节切片和符文切片不能相互转换,因此这里需要两个函数):

convertstrings[t1, t2 ~string | ~[]byte](t1 []t1) []t2 {}
// or
convertstrings[t1, t2 ~string | ~[]rune](t1 []t1) []t2 {}

复杂:

convertComplex[T1, T2 ~complex64 | ~complex128](t1 []T1) []T2 {}

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Golang 中的通用类型转换》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>