可以MAP'和'与仿制药一起实现

发布于 2025-02-07 19:23:23 字数 681 浏览 2 评论 0原文

我决定现在已经将仿制药引入了GO中,例如MAP/RELAD之类的东西是可能的。因此,我对此很天真地刺伤,我遇到了错误: ./ prog.go:18:36:无法将事物(INT类型的变量)用作i type i的参数to mapper

否则没有解释问题是否是基本的,或者我只是在做错事句法。可以在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
}

I decided that now that generics have been introduced into Go that something like map/reduce should be possible. So, I took a naive stab at it and I get the error:
./prog.go:18:36: cannot use thing (variable of type int) as type I in argument to mapper

Which doesn't explain if the problem is fundamental or I am simply doing something wrong syntactically. Can generic map/reduce be implemented in 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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的鱼塘能养鲲 2025-02-14 19:23:23

这可以很容易地完成。您的代码中有一个错误,尽管在这里:

for thing := range things {

您正在迭代索引值(int),而不是类型i的值。您还指定2个约束(类型io)都设置为接口{}。您只需使用而不是任何而不是(接口{}),

所以只需写入:

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
}

demo


这与我在CodeReview Exchange上评论的某些代码非常密切相关, - 用于传播阵列和映射函数,in-go-1-18/276128#276128“>在这里。浏览了代码并用大量建议编写片段后,我决定创建一个软件包并将其扔到github上。您可以找到repo 在这里

在其中,有一些示例可能会派上用场,或者可以帮助您通过Golang的其他一些Quirks 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
}

This can be done quite easily. You have an error in your code, though right here:

for thing := range things {

You are iterating over the index values (int), not the values of type I. You're also specifying 2 constraints (types I and O) both set to be interface{}. You can just use any instead (it's shorthand for interface{})

So simply write:

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
}

Demo


This is quite closely related to some code I reviewed on codereview exchange here. After going through the code, and writing snippets with a ton of suggestions, I decided to just create a package and throw it up on github instead. You can find the repo here.

In it, there's some examples that may come in handy, or help you work through some other quirks WRT generics in golang. I wsa specifically thinking about this bit, where you can filter a generic map type using callbacks like so:

// 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
}
往事风中埋 2025-02-14 19:23:23

您对range的使用不正确。从范围提取的单个变量将是索引(类型int),而不是值(type i,它仅偶然地INT在这种情况下)。

尝试

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

You have incorrect use of range. A single variable extracted from range will be the index (type int), not the value (type I, which is only coincidentally int in this case).

Try

for _, thing := range things{...}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文