mcpField
G
golang-samber-lo

golang-samber-lo

github.com/samber開発3.7k38.9k 回インストール6 日前に更新
リポジトリ

golang-samber-lo について

samber/lo を扱う Go スキルです。ジェネリクスベースのユーティリティによる宣言的なコレクション変換を説明し、標準ライブラリを優先する場面や関連パッケージの選び方も示します。

主な機能

  1. 01スライスとマップ向けのジェネリック関数
  2. 02データの変換、絞り込み、集約、グループ化
  3. 03エラーを返す関数バリアント
  4. 04並列・可変・イテレータの各パッケージ
  5. 05標準ライブラリの選択とプロファイリング指針

活用シーン

  1. 01定型的なコレクションループの置き換え
  2. 02データ変換パイプラインの構成
  3. 03計測後に遅延処理や並列処理を選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/samber/cc-skills-golang --skill golang-samber-lo

インストール後、Claude Code で/golang-samber-loを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
evals.json
references/
advanced-patterns.md
api-reference.md
package-guide.md

詳細

ペルソナ: 手動ループより宣言的なコレクション変換を好む Go エンジニアです。ボイラープレートをなくすために lo を使いますが、標準ライブラリで十分な場合や、lop、lom、loi に切り替えるべきタイミングも把握しています。

samber/lo — Go 向け関数型ユーティリティ

Lodash に着想を得た、ジェネリクスを優先するユーティリティライブラリです。スライス、マップ、文字列、数学、チャネル、タプル、並行処理向けに、型安全なヘルパーを 500 個以上提供します。外部依存関係はゼロです。デフォルトでは不変です。

公式リソース:

このスキルは網羅的なものではありません。詳しくは、ライブラリのドキュメントとコード例を参照してください。

  • Go パッケージのドキュメント、シンボル、バージョン、インポーター、既知の脆弱性については、→ samber/cc-skills-golang@golang-pkg-go-dev スキル(godig)を参照してください。Go パッケージの情報については、Context7 よりもこちらを優先してください。
  • 自分のコード内でこのライブラリの使い方(定義、呼び出し箇所、診断)を調べるには、→ samber/cc-skills-golang@golang-gopls スキル(gopls)を参照してください。
  • Context7 は、pkg.go.dev でインデックス化されていないドキュメントのフォールバックとして引き続き利用できます。

samber/lo を選ぶ理由

Go の標準ライブラリにある slices および maps パッケージが提供するのは、基本的なヘルパー(ソート、含有確認、キー取得など)約 10 個です。それ以外の Map、Filter、Reduce、GroupBy、Chunk、Flatten、Zip などには、手動の for ループが必要です。lo はこの不足を補います。

  • 型安全なジェネリクス — interface{} のキャストやリフレクションが不要で、コンパイル時に型がチェックされ、インターフェースボックス化によるオーバーヘッドもありません
  • デフォルトで不変 — 新しいコレクションを返すため、並行読み取りでも安全で、動作を把握しやすくなります
  • 合成可能 — 関数はスライスやマップを受け取り、返すため、ラッパー型なしで連結できます
  • 依存関係ゼロ — Go 標準ライブラリのみを使用し、推移的依存関係のリスクがありません
  • 段階的な複雑さ — lo から始め、プロファイリングで必要性が確認された場合にのみ lop/lom/loi に切り替えます
  • エラー対応のバリエーション — 多くの関数には Err サフィックス付きのバリエーション(MapErr、FilterErr、ReduceErr)があり、最初のエラーで処理を停止します

インストール

go get github.com/samber/lo
パッケージインポートエイリアスGo バージョン
Core(不変)github.com/samber/lolo1.18+
Parallelgithub.com/samber/lo/parallellop1.18+
Mutablegithub.com/samber/lo/mutablelom1.18+
Iteratorgithub.com/samber/lo/itloi1.23+
SIMD(実験的)github.com/samber/lo/exp/simd—1.25+(amd64 のみ)

適切なパッケージを選ぶ

まずは lo を使ってください。他のパッケージへの切り替えは、プロファイリングでボトルネックが確認された場合や、遅延評価が明示的に必要な場合に限ります。

パッケージ使用する場面トレードオフ
loすべての変換におけるデフォルト新しいコレクションを割り当てます(安全で予測可能)
lop大規模なデータセット(1000+ 項目)に対する CPU バウンド処理ゴルーチンのオーバーヘッドがあります。I/O や小さなスライスには不向きです
lompprof -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 — 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)
}
Filter + Reduce
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
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)
})

よくある間違い

間違い問題が起きる理由修正方法
slices.Contains があるのに lo.Contains を使う標準ライブラリで提供されている操作に不要な依存関係が生じますGo 1.21 以降では slices.Contains/slices.Sort を、キーのスライスが必要な場合は Go 1.23 以降で slices.Collect(maps.Keys(m)) を優先します
10 個の要素に lop.Map を使うゴルーチンの生成コストが変換コストを上回りますlo.Map を使います。lop の効果が得られるのは、CPU バウンドの処理でおよそ 1000 個以上の要素がある場合です
lo.Filter が入力を変更すると想定するlo はデフォルトでイミュータブルであり、新しいスライスを返しますインプレースでの変更が明示的に必要な場合は lom.Filter を使います
本番コードの処理経路で lo.Must を使うエラーが発生すると Must はパニックを起こします。テストや初期化では問題ありませんが、リクエストハンドラーでは危険ですMust を使わないバリアントを使い、エラーを処理します
大きなデータに対して遅延評価されない変換を何度も連結する各ステップで中間スライスが割り当てられますloi(遅延イテレーター)を使って、中間割り当てを回避します

ベストプラクティス

  1. 利用できる場合は標準ライブラリを優先します — slices.Contains と slices.Sort(Go 1.21 以降)は依存関係を必要としません。maps.Keys は Go 1.23 以降で利用でき、イテレーターを返すため、スライスが必要な場合は slices.Collect(maps.Keys(m)) を使います。標準ライブラリにない変換(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.Map と手動でのエラー収集を組み合わせるのではなく、lo.MapErr を優先します。エラー処理用のバリアントは早期に処理を停止し、エラーを適切に伝播します
  5. lo.Must はテストと初期化でのみ使います — 本番コードでは、エラーを明示的に処理します

クイックリファレンス

関数動作
lo.Map各要素を変換します
lo.Filter / lo.Reject条件を満たす要素を残す/除外します
lo.Reduce要素を単一の値に畳み込みます
lo.ForEach副作用を伴う反復処理を行います
lo.GroupByキーに基づいて要素をグループ化します
lo.Chunk固定サイズのバッチに分割します
lo.Flattenネストしたスライスを 1 階層平坦化します
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.Unzip22 つのスライスをペアにする/ペアを解除します
lo.Range / lo.RangeFrom数値のシーケンスを生成します
lo.Ternary / lo.Ifインライン条件分岐を行います
lo.ToPtr / lo.FromPtrポインター関連のヘルパーです
lo.Must / lo.Tryエラー時にパニックを起こす/エラーをブール値として復元します
lo.Async / lo.Attempt非同期実行/バックオフを伴う再試行を行います
lo.Debounce / lo.Throttleレート制限を行います
lo.ChannelDispatcher複数のチャネルにファンアウトします

関数の完全なカタログ(300 以上の関数)は、API リファレンスを参照してください。

関数の組み合わせパターン、標準ライブラリとの連携、イテレーターパイプラインについては、高度なパターンを参照してください。

samber/lo でバグや予期しない動作が発生した場合は、github.com/samber/lo/issues で issue を作成してください。

関連項目

  • → 無限イベントストリーム上のリアクティブ/ストリーミングパイプライン(samber/ro パッケージ)については、samber/cc-skills-golang@golang-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 スキルを参照してください

コメント