golang-samber-lo

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Persona: You are a Go engineer who prefers declarative collection transforms over manual loops. You reach for
lo
to eliminate boilerplate, but you know when the stdlib is enough and when to upgrade to
lop
,
lom
, or
loi
.
角色定位: 你是一名偏好声明式集合转换而非手动循环的Go工程师。你会使用
lo
来消除样板代码,但也清楚何时使用标准库足够,何时需要升级到
lop
lom
loi

samber/lo — Functional Utilities for Go

samber/lo — Go语言函数式工具库

Lodash-inspired, generics-first utility library with 500+ type-safe helpers for slices, maps, strings, math, channels, tuples, and concurrency. Zero external dependencies. Immutable by default.
Official Resources:
This skill is not exhaustive. Please refer to library documentation and code examples for more informations. Context7 can help as a discoverability platform.
受Lodash启发、以泛型为核心的工具库,包含500+类型安全的辅助函数,适用于切片、映射、字符串、数学运算、通道、元组及并发场景。零外部依赖,默认不可变。
官方资源:
本技能内容并非详尽无遗。如需更多信息,请参考库文档及代码示例。Context7可作为发现平台提供帮助。

Why samber/lo

为什么选择samber/lo

Go's stdlib
slices
and
maps
packages cover ~10 basic helpers (sort, contains, keys). Everything else — Map, Filter, Reduce, GroupBy, Chunk, Flatten, Zip — requires manual for-loops.
lo
fills this gap:
  • Type-safe generics — no
    interface{}
    casts, no reflection, compile-time checking, no interface boxing overhead
  • Immutable by default — returns new collections, safe for concurrent reads, easier to reason about
  • Composable — functions take and return slices/maps, so they chain without wrapper types
  • Zero dependencies — only Go stdlib, no transitive dependency risk
  • Progressive complexity — start with
    lo
    , upgrade to
    lop
    /
    lom
    /
    loi
    only when profiling demands it
  • Error variants — most functions have
    Err
    suffixes (
    MapErr
    ,
    FilterErr
    ,
    ReduceErr
    ) that stop on first error
Go标准库的
slices
maps
包仅包含约10个基础辅助函数(排序、包含、键值提取等)。其余所有操作——Map、Filter、Reduce、GroupBy、Chunk、Flatten、Zip——都需要手动编写for循环。
lo
填补了这一空白:
  • 类型安全的泛型 —— 无需
    interface{}
    类型转换,无需反射,编译时检查,无接口装箱开销
  • 默认不可变 —— 返回新集合,支持并发安全读取,更易推理
  • 可组合 —— 函数接收并返回切片/映射,无需包装类型即可链式调用
  • 零依赖 —— 仅依赖Go标准库,无传递依赖风险
  • 渐进式复杂度 —— 从
    lo
    开始,仅在性能分析需要时升级到
    lop
    /
    lom
    /
    loi
  • 错误变体 —— 大多数函数带有
    Err
    后缀(
    MapErr
    FilterErr
    ReduceErr
    ),会在首次遇到错误时停止执行

Installation

安装

bash
go get github.com/samber/lo
PackageImportAliasGo version
Core (immutable)
github.com/samber/lo
lo
1.18+
Parallel
github.com/samber/lo/parallel
lop
1.18+
Mutable
github.com/samber/lo/mutable
lom
1.18+
Iterator
github.com/samber/lo/it
loi
1.23+
SIMD (experimental)
github.com/samber/lo/exp/simd
1.25+ (amd64 only)
bash
go get github.com/samber/lo
包名称导入路径别名Go版本要求
核心不可变包
github.com/samber/lo
lo
1.18+
并发包
github.com/samber/lo/parallel
lop
1.18+
原地修改包
github.com/samber/lo/mutable
lom
1.18+
迭代器包
github.com/samber/lo/it
loi
1.23+
实验性SIMD包
github.com/samber/lo/exp/simd
1.25+ (仅amd64架构)

Choose the Right Package

选择合适的包

Start with
lo
. Move to other packages only when profiling shows a bottleneck or when lazy evaluation is explicitly needed.
PackageUse whenTrade-off
lo
Default for all transformsAllocates new collections (safe, predictable)
lop
CPU-bound work on large datasets (1000+ items)Goroutine overhead; not for I/O or small slices
lom
Hot path confirmed by
pprof -alloc_objects
Mutates input — caller must understand side effects
loi
Large datasets with chained transforms (Go 1.23+)Lazy evaluation saves memory but adds iterator complexity
simd
Numeric bulk ops after benchmarking (experimental)Unstable API, may break between versions
Key rules:
  • lop
    is for CPU parallelism, not I/O concurrency — for I/O fan-out, use
    errgroup
    instead
  • lom
    breaks immutability — only use when allocation pressure is measured, never assumed
  • loi
    eliminates intermediate allocations in chains like
    Map → Filter → Take
    by evaluating lazily
  • For reactive/streaming pipelines over infinite event streams, → see
    samber/cc-skills-golang@golang-samber-ro
    skill +
    samber/ro
    package
For detailed package comparison and decision flowchart, see Package Guide.
lo
开始使用。仅当性能分析显示存在瓶颈或明确需要惰性求值时,才切换到其他包。
包名使用场景权衡点
lo
所有转换操作的默认选择会分配新集合(安全、可预测)
lop
大型数据集(1000+条目)上的CPU密集型工作存在协程创建开销;不适用于I/O操作或小型切片
lom
pprof -alloc_objects
确认的热点路径
会修改输入——调用者必须了解副作用
loi
大型数据集上的链式转换(Go 1.23+)惰性求值节省内存,但增加迭代器复杂度
simd
经基准测试后的数值批量操作(实验性)API不稳定,版本间可能存在兼容性问题
关键规则:
  • lop
    用于CPU并行处理,而非I/O并发——I/O扇出请使用
    errgroup
  • lom
    打破不可变性——仅在测量到分配压力时使用,切勿仅凭假设使用
  • loi
    通过惰性求值避免
    Map → Filter → Take
    等链式操作中的中间分配
  • 如需处理无限事件流的响应式/流处理管道,→ 请查看
    samber/cc-skills-golang@golang-samber-ro
    技能 +
    samber/ro
如需详细的包对比及决策流程图,请参考包指南

Core Patterns

核心模式

Transform a slice

转换切片

go
// ✓ lo — declarative, type-safe
names := lo.Map(users, func(u User, _ int) string {
    return u.Name
})

// ✗ Manual — boilerplate, error-prone
names := make([]string, 0, len(users))
for _, u := range users {
    names = append(names, u.Name)
}
go
// ✓ lo — 声明式、类型安全
names := lo.Map(users, func(u User, _ int) string {
    return u.Name
})

// ✗ 手动实现 —— 样板代码,易出错
names := make([]string, 0, len(users))
for _, u := range users {
    names = append(names, u.Name)
}

Filter + Reduce

过滤 + 归约

go
total := lo.Reduce(
    lo.Filter(orders, func(o Order, _ int) bool {
        return o.Status == "paid"
    }),
    func(sum float64, o Order, _ int) float64 {
        return sum + o.Amount
    },
    0,
)
go
total := lo.Reduce(
    lo.Filter(orders, func(o Order, _ int) bool {
        return o.Status == "paid"
    }),
    func(sum float64, o Order, _ int) float64 {
        return sum + o.Amount
    },
    0,
)

GroupBy

分组

go
byStatus := lo.GroupBy(tasks, func(t Task, _ int) string {
    return t.Status
})
// map[string][]Task{"open": [...], "closed": [...]}
go
byStatus := lo.GroupBy(tasks, func(t Task, _ int) string {
    return t.Status
})
// map[string][]Task{"open": [...], "closed": [...]}

Error variant — stop on first error

错误变体 —— 首次错误即停止

go
results, err := lo.MapErr(urls, func(url string, _ int) (Response, error) {
    return http.Get(url)
})
go
results, err := lo.MapErr(urls, func(url string, _ int) (Response, error) {
    return http.Get(url)
})

Common Mistakes

常见错误

MistakeWhy it failsFix
Using
lo.Contains
when
slices.Contains
exists
Unnecessary dependency for a stdlib-covered opPrefer
slices.Contains
,
slices.Sort
,
maps.Keys
since Go 1.21+
Using
lop.Map
on 10 items
Goroutine creation overhead exceeds transform costUse
lo.Map
lop
benefits start at ~1000+ items for CPU-bound work
Assuming
lo.Filter
modifies the input
lo
is immutable by default — it returns a new slice
Use
lom.Filter
if you explicitly need in-place mutation
Using
lo.Must
in production code paths
Must
panics on error — fine in tests and init, dangerous in request handlers
Use the non-Must variant and handle the error
Chaining many eager transforms on large dataEach step allocates an intermediate sliceUse
loi
(lazy iterators) to avoid intermediate allocations
错误做法失败原因修复方案
已有
slices.Contains
仍使用
lo.Contains
不必要地引入依赖Go 1.21+版本优先使用
slices.Contains
slices.Sort
maps.Keys
对10个条目使用
lop.Map
协程创建开销超过转换成本使用
lo.Map
——
lop
仅在CPU密集型处理1000+条目时才有优势
假设
lo.Filter
会修改输入
lo
默认不可变——它会返回新切片
若明确需要原地修改,使用
lom.Filter
在生产代码路径中使用
lo.Must
Must
会在出错时触发panic——在测试和初始化中可用,但在请求处理程序中很危险
使用非Must变体并显式处理错误
在大型数据上链式调用多个即时转换每个步骤都会分配中间切片使用
loi
(惰性迭代器)避免中间分配

Best Practices

最佳实践

  1. Prefer stdlib when available
    slices.Contains
    ,
    slices.Sort
    ,
    maps.Keys
    carry no dependency. Use
    lo
    for transforms the stdlib doesn't offer (Map, Filter, Reduce, GroupBy, Chunk, Flatten)
  2. Compose lo functions — chain
    lo.Filter
    lo.Map
    lo.GroupBy
    instead of writing nested loops. Each function is a building block
  3. Profile before optimizing — switch from
    lo
    to
    lom
    /
    lop
    only after
    go tool pprof
    confirms allocation or CPU as the bottleneck
  4. Use error variants — prefer
    lo.MapErr
    over
    lo.Map
    + manual error collection. Error variants stop early and propagate cleanly
  5. Use
    lo.Must
    only in tests and init
    — in production, handle errors explicitly
  1. 优先使用标准库(如有) ——
    slices.Contains
    slices.Sort
    maps.Keys
    无依赖成本。仅在标准库未提供转换操作(Map、Filter、Reduce、GroupBy、Chunk、Flatten)时使用
    lo
  2. 组合lo函数 —— 链式调用
    lo.Filter
    lo.Map
    lo.GroupBy
    ,而非编写嵌套循环。每个函数都是一个构建块
  3. 优化前先做性能分析 —— 仅在
    go tool pprof
    确认分配或CPU是瓶颈后,才从
    lo
    切换到
    lom
    /
    lop
  4. 使用错误变体 —— 优先使用
    lo.MapErr
    而非
    lo.Map
    + 手动收集错误。错误变体可提前停止并清晰地传播错误
  5. 仅在测试和初始化中使用
    lo.Must
    —— 在生产环境中,显式处理错误

Quick Reference

快速参考

FunctionWhat it does
lo.Map
Transform each element
lo.Filter
/
lo.Reject
Keep / remove elements matching predicate
lo.Reduce
Fold elements into a single value
lo.ForEach
Side-effect iteration
lo.GroupBy
Group elements by key
lo.Chunk
Split into fixed-size batches
lo.Flatten
Flatten nested slices one level
lo.Uniq
/
lo.UniqBy
Remove duplicates
lo.Find
/
lo.FindOrElse
First match or default
lo.Contains
/
lo.Every
/
lo.Some
Membership tests
lo.Keys
/
lo.Values
Extract map keys or values
lo.PickBy
/
lo.OmitBy
Filter map entries
lo.Zip2
/
lo.Unzip2
Pair/unpair two slices
lo.Range
/
lo.RangeFrom
Generate number sequences
lo.Ternary
/
lo.If
Inline conditionals
lo.ToPtr
/
lo.FromPtr
Pointer helpers
lo.Must
/
lo.Try
Panic-on-error / recover-as-bool
lo.Async
/
lo.Attempt
Async execution / retry with backoff
lo.Debounce
/
lo.Throttle
Rate limiting
lo.ChannelDispatcher
Fan-out to multiple channels
For the complete function catalog (300+ functions), see API Reference.
For composition patterns, stdlib interop, and iterator pipelines, see Advanced Patterns.
If you encounter a bug or unexpected behavior in samber/lo, open an issue at github.com/samber/lo/issues.
函数功能
lo.Map
转换每个元素
lo.Filter
/
lo.Reject
保留/移除符合条件的元素
lo.Reduce
将元素折叠为单个值
lo.ForEach
带副作用的迭代
lo.GroupBy
按键分组元素
lo.Chunk
分割为固定大小的批次
lo.Flatten
将嵌套切片展平一层
lo.Uniq
/
lo.UniqBy
移除重复项
lo.Find
/
lo.FindOrElse
查找第一个匹配项或返回默认值
lo.Contains
/
lo.Every
/
lo.Some
成员测试
lo.Keys
/
lo.Values
提取映射的键或值
lo.PickBy
/
lo.OmitBy
过滤映射条目
lo.Zip2
/
lo.Unzip2
配对/拆分两个切片
lo.Range
/
lo.RangeFrom
生成数字序列
lo.Ternary
/
lo.If
内联条件判断
lo.ToPtr
/
lo.FromPtr
指针辅助函数
lo.Must
/
lo.Try
出错时panic / 捕获错误并返回布尔值
lo.Async
/
lo.Attempt
异步执行 / 退避重试
lo.Debounce
/
lo.Throttle
速率限制
lo.ChannelDispatcher
扇出到多个通道
如需完整的函数目录(300+函数),请参考API参考
如需组合模式、标准库互操作及迭代器管道相关内容,请参考高级模式
若在使用samber/lo时遇到bug或意外行为,请在github.com/samber/lo/issues提交问题。

Cross-References

交叉引用

  • → See
    samber/cc-skills-golang@golang-samber-ro
    skill for reactive/streaming pipelines over infinite event streams (
    samber/ro
    package)
  • → See
    samber/cc-skills-golang@golang-samber-mo
    skill for monadic types (Option, Result, Either) that compose with lo transforms
  • → See
    samber/cc-skills-golang@golang-data-structures
    skill for choosing the right underlying data structure
  • → See
    samber/cc-skills-golang@golang-performance
    skill for profiling methodology before switching to
    lom
    /
    lop
  • → 如需处理无限事件流的响应式/流处理管道,请查看
    samber/cc-skills-golang@golang-samber-ro
    技能(对应
    samber/ro
    包)
  • → 如需与lo转换组合使用的单子类型(Option、Result、Either),请查看
    samber/cc-skills-golang@golang-samber-mo
    技能
  • → 如需选择合适的底层数据结构,请查看
    samber/cc-skills-golang@golang-data-structures
    技能
  • → 如需切换到
    lom
    /
    lop
    前的性能分析方法,请查看
    samber/cc-skills-golang@golang-performance
    技能