golang-samber-lo
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePersona: You are a Go engineer who prefers declarative collection transforms over manual loops. You reach for to eliminate boilerplate, but you know when the stdlib is enough and when to upgrade to , , or .
loloplomloi角色定位: 你是一名偏好声明式集合转换而非手动循环的Go工程师。你会使用来消除样板代码,但也清楚何时使用标准库足够,何时需要升级到、或。
loloplomloisamber/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 and packages cover ~10 basic helpers (sort, contains, keys). Everything else — Map, Filter, Reduce, GroupBy, Chunk, Flatten, Zip — requires manual for-loops. fills this gap:
slicesmapslo- Type-safe generics — no casts, no reflection, compile-time checking, no interface boxing overhead
interface{} - 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 , upgrade to
lo/lop/lomonly when profiling demands itloi - Error variants — most functions have suffixes (
Err,MapErr,FilterErr) that stop on first errorReduceErr
Go标准库的和包仅包含约10个基础辅助函数(排序、包含、键值提取等)。其余所有操作——Map、Filter、Reduce、GroupBy、Chunk、Flatten、Zip——都需要手动编写for循环。填补了这一空白:
slicesmapslo- 类型安全的泛型 —— 无需类型转换,无需反射,编译时检查,无接口装箱开销
interface{} - 默认不可变 —— 返回新集合,支持并发安全读取,更易推理
- 可组合 —— 函数接收并返回切片/映射,无需包装类型即可链式调用
- 零依赖 —— 仅依赖Go标准库,无传递依赖风险
- 渐进式复杂度 —— 从开始,仅在性能分析需要时升级到
lo/lop/lomloi - 错误变体 —— 大多数函数带有后缀(
Err、MapErr、FilterErr),会在首次遇到错误时停止执行ReduceErr
Installation
安装
bash
go get github.com/samber/lo| Package | Import | Alias | Go version |
|---|---|---|---|
| Core (immutable) | | | 1.18+ |
| Parallel | | | 1.18+ |
| Mutable | | | 1.18+ |
| Iterator | | | 1.23+ |
| SIMD (experimental) | | — | 1.25+ (amd64 only) |
bash
go get github.com/samber/lo| 包名称 | 导入路径 | 别名 | Go版本要求 |
|---|---|---|---|
| 核心不可变包 | | | 1.18+ |
| 并发包 | | | 1.18+ |
| 原地修改包 | | | 1.18+ |
| 迭代器包 | | | 1.23+ |
| 实验性SIMD包 | | — | 1.25+ (仅amd64架构) |
Choose the Right Package
选择合适的包
Start with . Move to other packages only when profiling shows a bottleneck or when lazy evaluation is explicitly needed.
lo| Package | Use when | Trade-off |
|---|---|---|
| Default for all transforms | Allocates new collections (safe, predictable) |
| CPU-bound work on large datasets (1000+ items) | Goroutine overhead; not for I/O or small slices |
| Hot path confirmed by | Mutates input — caller must understand side effects |
| Large datasets with chained transforms (Go 1.23+) | Lazy evaluation saves memory but adds iterator complexity |
| Numeric bulk ops after benchmarking (experimental) | Unstable API, may break between versions |
Key rules:
- is for CPU parallelism, not I/O concurrency — for I/O fan-out, use
lopinsteaderrgroup - breaks immutability — only use when allocation pressure is measured, never assumed
lom - eliminates intermediate allocations in chains like
loiby evaluating lazilyMap → Filter → Take - For reactive/streaming pipelines over infinite event streams, → see skill +
samber/cc-skills-golang@golang-samber-ropackagesamber/ro
For detailed package comparison and decision flowchart, see Package Guide.
从开始使用。仅当性能分析显示存在瓶颈或明确需要惰性求值时,才切换到其他包。
lo| 包名 | 使用场景 | 权衡点 |
|---|---|---|
| 所有转换操作的默认选择 | 会分配新集合(安全、可预测) |
| 大型数据集(1000+条目)上的CPU密集型工作 | 存在协程创建开销;不适用于I/O操作或小型切片 |
| 经 | 会修改输入——调用者必须了解副作用 |
| 大型数据集上的链式转换(Go 1.23+) | 惰性求值节省内存,但增加迭代器复杂度 |
| 经基准测试后的数值批量操作(实验性) | API不稳定,版本间可能存在兼容性问题 |
关键规则:
- 用于CPU并行处理,而非I/O并发——I/O扇出请使用
loperrgroup - 打破不可变性——仅在测量到分配压力时使用,切勿仅凭假设使用
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
常见错误
| Mistake | Why it fails | Fix |
|---|---|---|
Using | Unnecessary dependency for a stdlib-covered op | Prefer |
Using | Goroutine creation overhead exceeds transform cost | Use |
Assuming | | Use |
Using | | Use the non-Must variant and handle the error |
| Chaining many eager transforms on large data | Each step allocates an intermediate slice | Use |
| 错误做法 | 失败原因 | 修复方案 |
|---|---|---|
已有 | 不必要地引入依赖 | Go 1.21+版本优先使用 |
对10个条目使用 | 协程创建开销超过转换成本 | 使用 |
假设 | | 若明确需要原地修改,使用 |
在生产代码路径中使用 | | 使用非Must变体并显式处理错误 |
| 在大型数据上链式调用多个即时转换 | 每个步骤都会分配中间切片 | 使用 |
Best Practices
最佳实践
- Prefer stdlib when available — ,
slices.Contains,slices.Sortcarry no dependency. Usemaps.Keysfor transforms the stdlib doesn't offer (Map, Filter, Reduce, GroupBy, Chunk, Flatten)lo - Compose lo functions — chain →
lo.Filter→lo.Mapinstead of writing nested loops. Each function is a building blocklo.GroupBy - Profile before optimizing — switch from to
lo/lomonly afterlopconfirms allocation or CPU as the bottleneckgo tool pprof - Use error variants — prefer over
lo.MapErr+ manual error collection. Error variants stop early and propagate cleanlylo.Map - Use only in tests and init — in production, handle errors explicitly
lo.Must
- 优先使用标准库(如有) —— 、
slices.Contains、slices.Sort无依赖成本。仅在标准库未提供转换操作(Map、Filter、Reduce、GroupBy、Chunk、Flatten)时使用maps.Keyslo - 组合lo函数 —— 链式调用→
lo.Filter→lo.Map,而非编写嵌套循环。每个函数都是一个构建块lo.GroupBy - 优化前先做性能分析 —— 仅在确认分配或CPU是瓶颈后,才从
go tool pprof切换到lo/lomlop - 使用错误变体 —— 优先使用而非
lo.MapErr+ 手动收集错误。错误变体可提前停止并清晰地传播错误lo.Map - 仅在测试和初始化中使用—— 在生产环境中,显式处理错误
lo.Must
Quick Reference
快速参考
| Function | What it does |
|---|---|
| Transform each element |
| Keep / remove elements matching predicate |
| Fold elements into a single value |
| Side-effect iteration |
| Group elements by key |
| Split into fixed-size batches |
| Flatten nested slices one level |
| Remove duplicates |
| First match or default |
| Membership tests |
| Extract map keys or values |
| Filter map entries |
| Pair/unpair two slices |
| Generate number sequences |
| Inline conditionals |
| Pointer helpers |
| Panic-on-error / recover-as-bool |
| Async execution / retry with backoff |
| Rate limiting |
| 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.
| 函数 | 功能 |
|---|---|
| 转换每个元素 |
| 保留/移除符合条件的元素 |
| 将元素折叠为单个值 |
| 带副作用的迭代 |
| 按键分组元素 |
| 分割为固定大小的批次 |
| 将嵌套切片展平一层 |
| 移除重复项 |
| 查找第一个匹配项或返回默认值 |
| 成员测试 |
| 提取映射的键或值 |
| 过滤映射条目 |
| 配对/拆分两个切片 |
| 生成数字序列 |
| 内联条件判断 |
| 指针辅助函数 |
| 出错时panic / 捕获错误并返回布尔值 |
| 异步执行 / 退避重试 |
| 速率限制 |
| 扇出到多个通道 |
如需完整的函数目录(300+函数),请参考API参考。
如需组合模式、标准库互操作及迭代器管道相关内容,请参考高级模式。
若在使用samber/lo时遇到bug或意外行为,请在github.com/samber/lo/issues提交问题。
Cross-References
交叉引用
- → See skill for reactive/streaming pipelines over infinite event streams (
samber/cc-skills-golang@golang-samber-ropackage)samber/ro - → See skill for monadic types (Option, Result, Either) that compose with lo transforms
samber/cc-skills-golang@golang-samber-mo - → See skill for choosing the right underlying data structure
samber/cc-skills-golang@golang-data-structures - → See skill for profiling methodology before switching to
samber/cc-skills-golang@golang-performance/lomlop
- → 如需处理无限事件流的响应式/流处理管道,请查看技能(对应
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