如何修改TransNumbers函数以使其与泛型函数doubleG和tripleG一起工作

type trandformFn func(int) int

func transformNumbers(numbers *[]int, transform trandformFn) []int {
    dNumbers := []int{}
    for _, value := range *numbers {
        dNumbers = append(dNumbers, transform(value))
    }
    return dNumbers
}

func double(value int) int {
    return 2 * value
}

func triple(value int) int {
    return 3 * value
}

func doubleG[T int | float64 | float32](value T) T {
    return 2 * value
}

func tripleG[T int | float64 | float32](value T) T {
    return 3 * value
}

我对transformFn类型感到困惑.

try 一些类似的东西:

func transformNumbers(numbers *[]int, transform func[T int|float64|float32](T)T) []int {
    dNumbers := []int{}
    for _, value := range *numbers {
        dNumbers = append(dNumbers, transform(value))
    }
    return dNumbers
}

但是出错了!

func transformNumbers(numbers *[]int, transform func[T int|float64|float32](T)T) []int {
    dNumbers := []int{}
    for _, value := range *numbers {
        dNumbers = append(dNumbers, transform(value))
    }
    return dNumbers
}

预计这会起作用,但得到了错误!

推荐答案

如果要将泛型函数用作不实例化的另一个函数的参数,还必须使该函数成为泛型函数.另外,不要传递指向切片的指针,这是不必要的(切片值已经是包含指向后备数组的指针的头).见Are slices passed by value?

例如:

func transformNumbers[T int | float64 | float32](numbers []T, transform func(T) T) []T {
    dNumbers := []T{}
    for _, value := range numbers {
        dNumbers = append(dNumbers, transform(value))
    }
    return dNumbers
}

测试它:

fmt.Println(transformNumbers([]int{1, 2, 3}, doubleG))
fmt.Println(transformNumbers([]float32{1, 2, 3}, doubleG))
fmt.Println(transformNumbers([]float64{1, 2, 3}, tripleG))

这将输出(在Go Playground上try ):

[2 4 6]
[2 4 6]
[3 6 9]

当然,您可以为Transformer函数创建一个transformFn类型,它也必须是泛型的:

type transformFn[T int | float64 | float32] func(T) T

func transformNumbers[T int | float64 | float32](numbers []T, transform transformFn[T]) []T {
    dNumbers := []T{}
    for _, value := range numbers {
        dNumbers = append(dNumbers, transform(value))
    }
    return dNumbers
}

用法相同,试试Go Playground.

还可以为约束创建单独的类型,这样就不必重复允许的类型:

type allowedTypes interface {
    int | float64 | float32
}

type transformFn[T allowedTypes] func(T) T

func transformNumbers[T allowedTypes](numbers []T, transform transformFn[T]) []T {
    dNumbers := []T{}
    for _, value := range numbers {
        dNumbers = append(dNumbers, transform(value))
    }
    return dNumbers
}

另请注意,预分配结果切片并分配每个转换后的值(不使用append())会快得多,因此如下所示:

func transformNumbers[T int | float64 | float32](numbers []T, transform func(T) T) []T {
    dNumbers := make([]T, len(numbers))
    for i, value := range numbers {
        dNumbers[i] = transform(value)
    }
    return dNumbers
}

Go相关问答推荐

语法-for循环中的initit陈述是否允许分配?

macOS上GoLand 2023.3.4中的代码导航

由于索引器压缩比限制,扫描包含golang包的图像时,伪影XRAY失败

如何修复proxyconnect tcp:tls:第一条记录看起来不像tls握手

确定果朗CSV行中的字节数

Golang Gorm Fiber / argon2.Config 未定义

死锁 - 所有 goroutine 都处于睡眠状态(即使使用等待组)

Go:如何在不加载正文的情况下创建 http 代理通行证

AWS Lambda 中的 Websocket URL 超时达到错误

io.Reader 无限循环与 fmt.Fscan

当填充通道的函数调用未嵌入 goroutine 时,为什么我会遇到死锁?

缺少签名帮助文档

判断一个区域内的纬度/经度点

从Go中的随机日期开始以天为单位获取时间

在恒等函数中将类型 T 转换为类型 U

将接口方法的参数限制为几个允许的 struct ?

Golang Echo Labstack 如何在模板视图中调用函数/方法

Go:用于 XML 解码的嵌套 struct 中的提升字段

为什么在 goroutine 中声明时,benbjohnson/clock 模拟计时器不执行?

Golang 泛型同时具有接口和实现