golang-samber-lo

golang-samber-lo

熱門

Golang 的函數式程式設計輔助工具,使用 samber/lo — 500+ 個型別安全的泛型函式,用於切片、映射、通道、字串、數學、元組和並發(Map、Filter、Reduce、GroupBy、Chunk、Flatten、Find、Uniq 等)。核心不可變套件 (lo)、並發變體 (lo/parallel 別名 lop)、原地變異 (lo/mutable 別名 lom)、惰性迭代器 (lo/it 別名 loi,適用於 Go 1.23+),以及實驗性 SIMD (lo/exp/simd)。適用於使用或採用 samber/lo 時、程式碼庫匯入 github.com/samber/lo 時,或在 Go 中實作函數式資料轉換時。不適用於串流管線(→ 請參閱 `samber/cc-skills-golang@golang-samber-ro` 技能)。

2261星標
150分支
更新於 2026/6/6
SKILL.md
readonlyread-only
name
golang-samber-lo
description

Golang 的函數式程式設計輔助工具,使用 samber/lo — 500+ 個型別安全的泛型函式,用於切片、映射、通道、字串、數學、元組和並發(Map、Filter、Reduce、GroupBy、Chunk、Flatten、Find、Uniq 等)。核心不可變套件 (lo)、並發變體 (lo/parallel 別名 lop)、原地變異 (lo/mutable 別名 lom)、惰性迭代器 (lo/it 別名 loi,適用於 Go 1.23+),以及實驗性 SIMD (lo/exp/simd)。適用於使用或採用 samber/lo 時、程式碼庫匯入 github.com/samber/lo 時,或在 Go 中實作函數式資料轉換時。不適用於串流管線(→ 請參閱 `samber/cc-skills-golang@golang-samber-ro` 技能)。

角色設定: 你是一位偏好使用宣告式集合轉換而非手動迴圈的 Go 工程師。你會使用 lo 來消除樣板程式碼,但你知道何時標準函式庫已足夠,以及何時該升級到 loplomloi

samber/lo — Go 的函數式工具

受 Lodash 啟發、以泛型為優先的工具函式庫,提供 500+ 個型別安全的輔助函式,用於切片、映射、字串、數學、通道、元組和並發。零外部依賴。預設不可變。

官方資源:

此技能並非詳盡無遺。請參閱函式庫文件和程式碼範例以獲取更多資訊。Context7 可作為探索平台提供協助。如需 Go 套件文件、版本、符號和已知漏洞,→ 請參閱 samber/cc-skills-golang@golang-pkg-go-dev 技能。

為什麼選擇 samber/lo

Go 的標準函式庫 slicesmaps 套件涵蓋約 10 個基本輔助函式(排序、包含、鍵)。其他所有功能 — Map、Filter、Reduce、GroupBy、Chunk、Flatten、Zip — 都需要手動 for 迴圈。lo 填補了這個缺口:

  • 型別安全的泛型 — 無需 interface{} 轉型、無反射、編譯期檢查、無介面裝箱開銷
  • 預設不可變 — 回傳新集合,安全用於並發讀取,更容易推理
  • 可組合 — 函式接收並回傳切片/映射,因此無需包裝型別即可鏈式呼叫
  • 零依賴 — 僅依賴 Go 標準函式庫,無傳遞性依賴風險
  • 漸進式複雜度 — 從 lo 開始,僅在效能分析要求時升級到 lop/lom/loi
  • 錯誤變體 — 大多數函式有 Err 後綴(MapErrFilterErrReduceErr),在第一個錯誤時停止

安裝

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)

選擇正確的套件

lo 開始。僅在效能分析顯示瓶頸或明確需要惰性求值時,才轉移到其他套件。

套件 使用時機 取捨
lo 所有轉換的預設選擇 分配新集合(安全、可預測)
lop 大型資料集(1000+ 項目)的 CPU 密集型工作 Goroutine 開銷;不適用於 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 套件

如需詳細的套件比較和決策流程圖,請參閱 套件指南

核心模式

轉換切片

// ✓ 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)
}

過濾 + 歸納

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,
)

分組

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

錯誤變體 — 在第一個錯誤時停止

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

常見錯誤

錯誤 失敗原因 修正
使用 lo.Containsslices.Contains 已存在 對標準函式庫已涵蓋的操作引入不必要的依賴 自 Go 1.21+ 起優先使用 slices.Contains/slices.Sort,自 Go 1.23+ 起需要鍵切片時使用 slices.Collect(maps.Keys(m))
對 10 個項目使用 lop.Map Goroutine 建立開銷超過轉換成本 使用 lo.Maplop 的好處在 CPU 密集型工作中約從 1000+ 項目開始
假設 lo.Filter 會修改輸入 lo 預設不可變 — 它回傳一個新切片 如果明確需要原地變異,請使用 lom.Filter
在生產程式碼路徑中使用 lo.Must Must 在錯誤時 panic — 在測試和初始化中沒問題,但在請求處理程式中很危險 使用非 Must 變體並處理錯誤
對大型資料鏈接多個急切轉換 每個步驟分配一個中間切片 使用 loi(惰性迭代器)避免中間分配

最佳實踐

  1. 優先使用標準函式庫(如果可用)slices.Containsslices.Sort(Go 1.21+)無依賴;maps.Keys 是 Go 1.23+ 並回傳迭代器,因此當你需要切片時使用 slices.Collect(maps.Keys(m))。對於標準函式庫未提供的轉換(Map、Filter、Reduce、GroupBy、Chunk、Flatten),使用 lo
  2. 組合 lo 函式 — 鏈接 lo.Filterlo.Maplo.GroupBy,而不是撰寫巢狀迴圈。每個函式都是一個建構區塊
  3. 先分析再最佳化 — 僅在 go tool pprof 確認分配或 CPU 是瓶頸後,才從 lo 切換到 lom/lop
  4. 使用錯誤變體 — 優先使用 lo.MapErr 而非 lo.Map 加手動錯誤收集。錯誤變體提前停止並乾淨地傳播
  5. 僅在測試和初始化中使用 lo.Must — 在生產環境中,明確處理錯誤

快速參考

函式 功能
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 / 將 panic 轉為 bool
lo.Async / lo.Attempt 非同步執行 / 帶退避的重試
lo.Debounce / lo.Throttle 速率限制
lo.ChannelDispatcher 扇出到多個通道

如需完整的函式目錄(300+ 個函式),請參閱 API 參考

如需組合模式、標準函式庫互通和迭代器管線,請參閱 進階模式

如果你在 samber/lo 中遇到錯誤或意外行為,請在 github.com/samber/lo/issues 開啟問題。

交叉參考

  • → 請參閱 samber/cc-skills-golang@golang-samber-ro 技能,了解處理無限事件串流的反應式/串流管線(samber/ro 套件)
  • → 請參閱 samber/cc-skills-golang@golang-samber-mo 技能,了解可與 lo 轉換組合的單子型別(Option、Result、Either)
  • → 請參閱 samber/cc-skills-golang@golang-data-structures 技能,了解如何選擇正確的底層資料結構
  • → 請參閱 samber/cc-skills-golang@golang-performance 技能,了解在切換到 lom/lop 前的效能分析方法