可以使用泛型在 Go 中实现“映射”和“减少”吗

我决定既然泛型已经被引入到 Go 中,那么类似的东西map/reduce应该是可能的。所以,我天真地尝试了一下,我得到了错误: ./prog.go:18:36: cannot use thing (variable of type int) as type I in argument to mapper


这并不能解释问题是否是根本性的,或者我只是在语法上做错了什么。通用 map/reduce 可以在 Go 中实现吗?


package main


import "fmt"


func main() {

    things := []int{1, 2, 3, 4}

    results := Map(things, func(t int) int {

        return t + 1

    })

    fmt.Printf("%v", results)

}


func Map[I interface{}, O interface{}](things []I, mapper func(thing I) O) []O {

    results := make([]O, 0, len(things))

    for thing := range things {

        results = append(results, mapper(thing))

    }

    return results

}


慕沐林林
浏览 112回答 2
2回答

青春有我

您对 . 的使用不正确range。从中提取的单个变量range将是索引(类型int),而不是值(类型I,在这种情况下只是巧合int)。尝试for _, thing := range things{...}

守候你守候我

这可以很容易地完成。你的代码有错误,但就在这里:for thing := range things {您正在遍历索引值 (int),而不是 type 的值I。您还指定了 2 个约束(类型I和O)都设置为interface{}。您可以any改用(它是 的简写interface{})所以简单地写:func Map[T any, O any](things []T, mapper func(thing T) O) []O {    result := make([]O, 0, len(things))    for _, thing := range things {        result = append(result, mapper(thing))    }    return result}演示这与我在 codereview exchange here上审查的一些代码密切相关。在浏览了代码并编写了带有大量建议的片段之后,我决定只创建一个包并将其放在 github 上。你可以在这里找到回购协议。在其中,有一些示例可能会派上用场,或者帮助您解决 golang 中 WRT 泛型的其他一些怪癖。我特别考虑了这一点,您可以在其中使用回调来过滤通用地图类型,如下所示:// given the sMap typetype sMap[K comparable, V any] struct {    mu *sync.RWMutex    m  map[K]V}// Filter returns a map containing the elements that matched the filter callback argumentfunc (s *sMap[K, V]) Filter(cb func(K, V) bool) map[K]V {    s.mu.RLock()    defer s.mu.RUnlock()    ret := make(map[K]V, len(s.m))    for k, v := range s.m {        if cb(k, v) {            ret[k] = v        }    }    return ret}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go