Golang 中的通用 Map 函数

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

我正在学习 Golang,为了好玩,我尝试创建一个 Map 函数,它采用我的 Slice 包装器(其中包含使用 go 1.22 的 GOEXPERIMENT=rangefunc 的 Iter 函数)。但是在 Map 函数中,编译器给了我这个错误:“不能使用 i(int 类型的变量)作为 f 参数中的 T 值”。

type IterableSlice[T any] struct {
    slice []T
}

func (is IterableSlice[T]) Iter(yield func(T) bool) {
    for _, v := range is.slice {
        yield(v)
    }
}

func Map[T, V any](is IterableSlice[T], f func(T) V) IterableSlice[V] {
    var a []V

    for i := range is.slice {
        f(i)
    }

    return IterableSlice[V]{a}
}

func main() {
    a := []int{
        1, 2, 3, 4, 5,
    }

    is := IterableSlice[int]{a}

    var isf IterableSlice[float32]
    isf = Map(is, func(x int) float32 {
        return float32(x)
    })

    for i := range isf.Iter {
        fmt.Println(i)
    }
}

我正在尝试解决这个错误,或者至少理解这是在 Go 中不可能做到的事情

go functional-programming slice
2个回答
1
投票

问题在这里:

    for i := range is.slice {
        f(i)
    }

这里的

i
就是索引。该索引的类型为
int
。它无法传递给需要
f
类型值的
T

我想你想要的是:

    for _, i := range is.slice {
        f(i)
    }

没检查是否还有其他问题...


0
投票

Map
函数中的问题是由于尝试将索引(
i
)从
range
循环传递到函数
f
而不是切片中的值而引起的。
range
上的
is.slice
循环会产生索引和值,但在
Map
函数中,您错误地使用了索引。这是更正后的版本:

func Map[T, V any](is IterableSlice[T], f func(T) V) IterableSlice[V] {
    var a []V

    for _, v := range is.slice {
        // Apply the function `f` to each value `v` from the slice, not the index `i`.
        a = append(a, f(v))
    }

    return IterableSlice[V]{a}
}

此外,您在

Iter
函数中使用
main
函数是不正确的。
Iter
方法旨在为切片的每个元素执行提供的函数,而不是直接在
range
语句中使用。正确的用法如下:

func main() {
    a := []int{1, 2, 3, 4, 5}
    is := IterableSlice[int]{a}

    isf := Map(is, func(x int) float32 {
        return float32(x)
    })

    // Properly using the `Iter` method
    isf.Iter(func(v float32) bool {
        fmt.Println(v)
        return true // Indicates to continue the iteration
    })
}

在这个更正的方法中,

Iter
函数用于迭代切片
isf
中的每个元素,打印每个值。
yield
中的
Iter
函数返回一个布尔值来指示迭代是否应该继续,因此返回
true
确保所有元素都已处理。

© www.soinside.com 2019 - 2024. All rights reserved.