发布 v2 版 go-js-array-methods — JS 风格的 Filter、Map、Reduce 用于 Go 切片

发布: (2026年5月10日 GMT+8 06:57)
4 分钟阅读
原文: Dev.to

Source: Dev.to

快速体验

import "github.com/bube054/go-js-array-methods/v2/array"

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

even := array.Filter(nums, func(n, _ int, _ []int) bool { return n%2 == 0 })
doubled := array.Map(even, func(n, _ int, _ []int) int { return n * 2 })
// [4, 8]

或者链式调用,如果你喜欢这种风格:

arr := array.Array[int]{1, 2, 3, 4, 5}

result := arr.
    Filter(func(n, _ int, _ []int) bool { return n%2 == 0 }).
    Push(6).
    Reverse()
// [6, 4, 2]

两种风格可以互换。使用最适合你代码上下文的方式。

包含哪些方法

30+ 你真正会用到的方法:

  • Filter, Map, Reduce(以及 ReduceRight*Strict 变体,保持输入类型不变)
  • Find, FindIndex, FindLast, FindLastIndex
  • Every, Some, Includes, IndexOf, LastIndexOf
  • At, Slice, Splice, Push, Pop, Shift, Unshift
  • Concat, Reverse, Fill, CopyWithin, Flat, ForEach, Join
  • Entries, With, ToString, ValueOf

故意未实现的功能

  • Sort – Go 的 slices.Sortsort 包已经能够很好地完成排序。
  • Keys – 简单的 for i := range slice 已足够。
  • FlatMap – 计划在未来的版本中实现,欢迎贡献代码。

几件值得了解的事

默认不可变。 每个函数都会返回一个新切片;输入切片永不改变,即使是像 PushSplice 这样的“变异”方法。这可以避免别名导致的 bug。

负索引。 At(-1) 返回最后一个元素。Slice(s, -2, -1) 的行为类似 JavaScript。超出范围的访问会返回错误,而不是 panic。

Map 完全泛型。 编译器会从回调函数中推断输出类型,使调用处保持简洁:

nums := []int{1, 2, 3}
strs := array.Map(nums, func(n, _ int, _ []int) string {
    return fmt.Sprintf("#%d", n)
})
// []string{"#1", "#2", "#3"} – 无需类型断言,也不使用 []any

如果希望输出类型锁定为输入类型,请使用 MapStrict

Go 的怪癖。 Go 不允许在方法上使用类型参数,只能在函数上使用。因此 Array[T].Map() 只能用于 Array[any]。想要完全类型安全的 Map,请直接使用 array.Map 函数;链式风格仍然适用于其他方法。

我常用的几种模式

在不手动声明累加器的情况下求和切片

nums := []int{1, 2, 3, 4}
initial := 0
sum, _ := array.ReduceStrict(nums, func(acc, n, _ int, _ []int) int {
    return acc + n
}, &initial)
// sum == 10

将混合嵌套切片扁平化

nested := []any{1, []int{2, 3}, []int{4, 5}}
flat, _ := array.Flat[int](nested)
// []int{1, 2, 3, 4, 5}

在保持类型安全的前提下转换字符串切片

arr := array.Array[string]{"alice", "bob", "carol"}
shouts := arr.MapStrict(func(s string, _ int, _ []string) string {
    return strings.ToUpper(s) + "!"
})
// [ALICE! BOB! CAROL!]

更多带有输出的可运行示例请查看 array/example_test.gopkg.go.dev

如果你觉得有用

在仓库上点个星是一个很好的信号,能帮助我决定继续维护哪些项目。大多数 Go 开发者并不会自行发现这个库,往往会自己写手动循环。

如果你认识的人在 Go 中缺少 filter/map,分享这个库将是一个大帮助。提交缺失方法或边界情况的 Issue 非常有价值——尤其是当你能指明对应的 JavaScript 行为时。也欢迎提交 Pull Request。

链接

0 浏览
Back to Blog

相关文章

阅读更多 »

Bun 在 6 天内移植到 Rust

概览 - 测试覆盖率:在 Rust 重写版中,Bun 现有的测试套件在 Linux x64 glibc 上的通过率为 99.8%。 - 代码库基本保持不变,但 Ru...