如何将泛型函数作为参数传递给 golang 中的另一个函数?

问题描述 投票:0回答:1

如何修改transformNumbers函数,使其与通用函数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类型感到困惑。

尝试类似的事情:

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
}

期望这能起作用,但出现错误!

function go generics methods higher-order-functions
1个回答
0
投票

如果您想在不实例化的情况下使用泛型函数作为另一个函数的参数,则还必须将该函数设为泛型。另外,不要传递指向切片的指针,这是不必要的(切片值已经是包含指向后备数组的指针的标头)。请参阅切片是否按值传递?

例如:

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上尝试一下):

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

您当然可以为转换器函数创建一个

transformFn
类型,它也必须是通用的:

类型transformFn[T int |浮动64 | 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试试这个。

另请注意,预分配结果切片并分配每个转换后的值(不使用

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
}
© www.soinside.com 2019 - 2024. All rights reserved.