为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕沐林林 2022-12-19 21:35:44
我决定既然泛型已经被引入到 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 mainimport "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}
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

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

尝试

for _, thing := range things{...}


查看完整回答
反对 回复 2022-12-19
?
守候你守候我

TA贡献1802条经验 获得超10个赞

这可以很容易地完成。你的代码有错误,但就在这里:


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 type

type 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 argument

func (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

}


查看完整回答
反对 回复 2022-12-19
  • 2 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信