Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GoのGenericsによるslice操作との付き合い方
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
syumai
June 18, 2025
Programming
1.2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GoのGenericsによるslice操作との付き合い方
golang.tokyo #39 の発表資料です
https://golangtokyo.connpass.com/event/353988/
syumai
June 18, 2025
More Decks by syumai
See All by syumai
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
Oxlintのカスタムルールの現況
syumai
6
1.2k
Oxlintはいかにしてtsgolintのlint ruleを呼び出しているのか
syumai
2
1.3k
『[入門] Cloudflare Workers』本はなぜ誕生したのか
syumai
0
400
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
9
3.1k
知られているようで知られていない JavaScriptの仕様 4選
syumai
3
1.2k
CloudflareのSandbox SDKを試してみた
syumai
0
890
実践AIチャットボットUI実装入門
syumai
9
4.2k
ProxyによるWindow間RPC機構の構築
syumai
3
1.5k
Other Decks in Programming
See All in Programming
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
410
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
Webフレームワークの ベンチマークについて
yusukebe
0
180
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
190
スマートグラスで並列バイブコーディング
hyshu
0
260
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.3k
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
280
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
150
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.5k
Vite+ Unified Toolchain for the Web
naokihaba
0
360
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.5k
Performance Engineering for Everyone
elenatanasoiu
0
230
Featured
See All Featured
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
220
Discover your Explorer Soul
emna__ayadi
2
1.1k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.1k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Automating Front-end Workflow
addyosmani
1370
210k
KATA
mclloyd
PRO
35
15k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
160
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
72
40k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
450
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Transcript
Go のGenerics によるslice 操作との付き合い方 syumai golang.tokyo #39 (2025/6/18)
自己紹介 syumai ECMAScript 仕様輪読会 / Asakusa.go 主催 株式会社ベースマキナで管理画面のSaaS を開発中 Go
でGraphQL サーバー (gqlgen) や TypeScript でフロント エンドを書いています Software Design 2023 年12 月号から2025 年2 月号まで Cloudflare Workers の連載をしました Twitter ( 現𝕏): @__syumai Website: https://syum.ai
今日話すこと basemachina/lo の紹介 実装のモチベーション i. 従来のslice 操作の課題 ii. samber/lo 導入の課題
slice 変換機能の使い方 ( おまけ) イテレータの利用状況
basemachina/lo
basemachina/lo Generics を使って Map , Filter などの操作をslice に対して簡単に行えるライブラリ 型情報を使ったslice 以外の操作も必要に応じて追加している
numbers := []int{1, 2, 3, 4, 5} doubled := lo.Map(numbers, func(x int) int { return x * 2 }) fmt.Println(doubled) // [2, 4, 6, 8, 10] evens := lo.Filter(numbers, func(x int) bool { return x%2 == 0 }) fmt.Println(evens) // [2, 4] fmt.Printf("%T\n", lo.ToPtr(1)) // *int
現在使える機能 ( 全19 種類) * Array/Slice操作 - フィルタリング - Filter
- FilterWithIndex - 変換 - Map - MapWithError - MapWithIndex - MapWithIndexError - FlatMap - FlatMapWithIndex - 検索・判定 - Find - Every - Some - HasDuplicates - HasDuplicatesBy - 集約 - Reduce - ReduceWithIndex - 集合演算 - Intersect * Map操作 - Invert * ポインタ操作 - ToPtr - FromPtrOr
実装のモチベーション
1. 従来のslice 操作の課題
None
None
None
1. 従来のslice 操作の課題 range を使った詰め替えでは、うっかり事故る可能性がある lint を入れて防ぐしかない ( 私見) lo.Map
や lo.Filter などの関数を使ったコードの方が読むのが楽 行いたい操作が関数名から明確 slice 操作の実装の詳細を確認しなくていい
2. samber/lo 導入の課題
2. samber/lo 導入の課題 機能が充実しすぎている 全部を使いたい訳ではない 学習コストを問題視
https://pkg.go.dev/github.com/samber/lo
はてなさんの事例 https://github.com/hatena/godash 今はiter 推奨らしい
basemachina/lo のslice 変換機能の使い方
basemachina/lo のslice 変換機能の使い方 DB から取ってきたデータを変換してGraphQL resolver から返す処理 func (r *queryResolver)
Views(ctx context.Context) ([]*gql.View, error) { // []*model.View を取得 views, err := loader.ListViews(ctx, r.project.ID) if err != nil { return nil, err } // []*gql.View を返却 return lo.Map(views, gqlpresenter.View), nil }
basemachina/lo のslice 変換機能の使い方 basemachina/lo 無しの場合 func (r *queryResolver) Views(ctx context.Context)
([]*gql.View, error) { // []*model.View を取得 views, err := loader.ListViews(ctx, r.project.ID) if err != nil { return nil, err } // []*gql.View を返却 gqlViews := make([]*gql.View, len(views)) for i, v := range views { gqlViews[i] = gqlpresenter.View(v) } return gqlViews }
basemachina/lo のslice 変換機能の使い方 変換用のコードは使い回せるので別package で実装 lo.Map のシグニチャを変えて (item T, index
int) を (item T) だけにして いるのでこれでOK package gqlpresenter func View(v *model.View) *gql.View { return &gql.View{ ID: v.ID, Name: v.Name, Code: v.Code, } }
もし lo.Map のシグニチャが iteratee (item T, index int) だったら 変換処理側で合わせる場合
package gqlpresenter // 毎回 `_ int` を書かないといけない func View(v *model.View, _ int) *gql.View { return &gql.View{ ID: v.ID, Name: v.Name, Code: v.Code, } }
もし lo.Map のシグニチャが iteratee (item T, index int) だったら 変換処理を使う側で合わせる場合
func (r *queryResolver) Views(ctx context.Context) ([]*gql.View, error) { views, err := loader.ListViews(ctx, r.project.ID) if err != nil { return nil, err } // 毎回無名関数を書く return lo.Map(views, func (v *model.View, _ int) *gql.View { return gqlpresenter.View(v) }), nil }
basemachina/lo のslice 変換機能の使い方 変換時にエラーが発生しうる場合は lo.MapWithError を使う func (r *queryResolver) Actions(ctx
context.Context) ([]*gql.Action, error) { /* ... */ return lo.MapWithError(actions, gqlpresenter.Action) }
basemachina/lo のslice 変換機能の使い方 MapWithIndexError (MapWithError の内部で呼ぶ) の実装 https://github.com/samber/lo/pull/43 で提案 func
MapWithIndexError[T any, R any]( collection []T, iteratee func(item T, index int) (R, error)) ([]R, error) { result := make([]R, len(collection)) var err error for i, item := range collection { result[i], err = iteratee(item, i) if err != nil { return nil, err } } return result, nil }
( おまけ) イテレータの利用状況
イテレータ、積極的に使っていますか?
社内のイテレータの利用状況 社内では導入がほぼ進んでいない ほとんどがslice の変換だけで済んでしまうユースケースのみ
Go のxiter package proposal がClose データ列の変換目的でのイテレータ導入の理由は弱くなった https://github.com/golang/go/issues/61898
パフォーマンスチューニング目的での導入はありうる https://developers.cyberagent.co.jp/blog/archives/54653/
補足 - xiter 以外の選択肢 go-functional https://github.com/BooleanCat/go-functional Go のイテレータを使って関数型チックにコードを書けるライブラリ ヘルパー関数も充実している
まとめ
まとめ Generics を活用したslice 操作ライブラリの自前実装を持つのは便利 slice 操作のスタイルを統一できる イテレータを使わないslice 操作は残念ながらまだ現役
ご清聴ありがとうございました!