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の夢は広がるか? / Kyoto.go #65
Search
utagawa kiki
June 06, 2026
Programming
1.1k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
https://kyotogo.connpass.com/event/392816/
https://blog.utgw.net/entry/2026/06/07/123729
utagawa kiki
June 06, 2026
More Decks by utagawa kiki
See All by utagawa kiki
new(1.26) ← これすき / kamakura.go #8
utgwkk
0
4.3k
tparseでgo testの出力を見やすくする
utgwkk
2
2k
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
4
2.5k
自動で //nolint を挿入する取り組み / Gopher's Gathering
utgwkk
1
3.2k
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
utgwkk
2
4.5k
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
21
17k
Dive into gomock / Go Conference 2024
utgwkk
14
8.7k
Goでリフレクションする、その前に / Kansai.go #1
utgwkk
4
3.8k
Go製Webアプリケーションのエラーとの向き合い方大全、あるいはやっぱりスタックトレース欲しいやん / Kyoto.go #50
utgwkk
7
4.4k
Other Decks in Programming
See All in Programming
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
850
どこまでゆるくて許されるのか
tk3fftk
0
500
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
860
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
140
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
150
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
170
関数型プログラミングのメリットって何だろう?
wanko_it
0
180
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.9k
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
110
5分で問診!Composer セキュリティ健康診断
codmoninc
0
340
Featured
See All Featured
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
290
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Marketing to machines
jonoalderson
1
5.6k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Unsuck your backbone
ammeep
672
58k
Git: the NoSQL Database
bkeepers
PRO
432
67k
How STYLIGHT went responsive
nonsquared
100
6.2k
Ruling the World: When Life Gets Gamed
codingconduct
0
280
RailsConf 2023
tenderlove
30
1.5k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Building Adaptive Systems
keathley
44
3.1k
Transcript
メソッドのジェネリクスで Goの夢は広がるか? id:utgwkk / @utgwkk (うたがわきき) 2026/6/6 Kyoto.go #65 オフラインLT会@はてな
1
自己紹介 • うたがわきき (@utgwkk) • 株式会社はてな ◦ Webアプリケーションエンジニア ◦ 京都在住
• 好きなパッケージはreflect 2
今日の流れ • Go 1.27で導入されるメソッドのジェネリク スの話をします • その前に、これまでのGoのジェネリクスの話 をおさらいします 3
おしながき • ジェネリクス以前 ◦ Go ~1.17 • ジェネリクス以降 ◦ Go
1.18~ • メソッドのジェネリクスで広がる夢 ◦ Go 1.27?~ 4
ジェネリクス以前 (~1.17) • 任意の型に対する操作を書くときの選択肢は 以下3つ ◦ any型からキャスト ◦ リフレクション ◦
コード生成 • 長らくこれらで暮らしてきた 5
any型からキャスト • 任意の型を入れるコンテナ ◦ context.Context ◦ sync.Map • キャストして所望の型として扱う ◦
val, ok := ctx.Value(...).(*MyType) 6
リフレクション (1) • プログラムが実行時に自身の構造を操作する ◦ reflectパッケージを利用 • 任意の型を受け取って値を書き換える関数は だいたいリフレクションやってた ◦
ジェネリクスの導入で数は減った 7
リフレクション (2) • 自力でリフレクションするのは修羅 ◦ 失敗すると問答無用でpanicする ◦ やらなくて済むなら回避したほうがいい • 遅い
8
リフレクションの活用事例 (1) • 標準ライブラリ ◦ database/sql ◦ encoding/json, encoding/xml ◦
fmt ◦ sort ◦ text/template, html/template 9
リフレクションの活用事例 (2) • サードパーティーライブラリ ◦ github.com/caarlos0/env ▪ 環境変数→structのマッピング ◦ github.com/go-playground/validator
▪ バリデーション ◦ github.com/stretchr/testify ▪ テストのassertion 10
コード生成 (1) • プログラム中で使う範囲の実装を あらかじめ生成しておく • スキーマと相性が良い ◦ OpenAPI ◦
GraphQL ◦ protobuf 11
コード生成 (2) • コード生成の対象が多いとコード量が増える ◦ Git管理するか議論になりがち • パフォーマンスは出しやすい 12
コード生成の活用事例 • github.com/abice/go-enum ◦ enum型の定義を生成 • go.uber.org/mock/mockgen ◦ interfaceのモック実装を生成 •
github.com/99designs/gqlgen ◦ GraphQL APIのリゾルバ実装などを生成 13
おさらい: ジェネリクス以前 (~1.17) • 任意の型に対する操作を書くときの選択肢は 以下3つ ◦ any型からキャスト ◦ リフレクション
◦ コード生成 • 長らくこれらで暮らしてきた 14
ジェネリクスの導入 (1.18) • 汎用的な関数・型をジェネリクスで書ける • 嬉しさ ◦ 型・関数を使い回せる (場合がある) ◦
リフレクションが不要になる (場合がある) ◦ シグネチャがより直感的になる (場合がある) • ただし制約が強い 15
型・関数を使い回せる • database/sql ◦ nullableなカラムを表す型が分かれていた ▪ bool, []byte, float64, int{16,32,64},
string, time.Time 向けの型がそれぞれ定義されていた ◦ Null[T] 型を使えばよくなった 16
リフレクションが不要になる • スライスのsort ◦ sort.Slice関数は内部でリフレクションしていた ▪ sort.Interfaceを実装した型を用意したらリフレクション不 要にできるが、煩雑 ◦ slices.Sort関数はリフレクションしない
▪ 比較関数を渡したらよい 17
シグネチャがより直感的になる (1) • any型を渡すような関数の制約が明確になる ◦ 実行時エラーに悩まされづらくなる • errors.AsType関数 ◦ errors.As関数の代替
◦ エラーをUnwrapして型キャストする ◦ 間違った使い方をコンパイルエラーで検出できる 18
シグネチャがより直感的になる (2) var asErr *SomeError if ok := errors.As(err, &asErr);
ok { // asErr != nil } // 第2引数はerrorじゃなくても渡せてしまう 19
シグネチャがより直感的になる (3) if asErr, ok := errors.AsType[*SomeError](err); ok { //
asErr != nil } // ジェネリクスの型制約で errorであることが // コンパイル時に保証されている 20
Goのジェネリクスの限界 (1) • メソッドに型引数を渡せない ◦ func (x *List[T]) Map[U any](...)
▪ 文法的には書けるがコンパイルエラー ◦ Option型とか作るときに困りがち ▪ メソッドにできないので関数にする 21
Goのジェネリクスの限界 (2) • ジェネリックなinterfaceのメソッドへの対応 が困難だったため ◦ 独自型のメソッドをジェネリクス対応するなら interfaceもジェネリクス対応しないといけなくなる ◦ ジェネリックなinterfaceのメソッド呼び出しを効率
的に実装できない 22
おさらい: ジェネリクスの導入 (1.18) • 汎用的な関数・型をジェネリクスで書ける • 嬉しさ ◦ 型・関数を使い回せる (場合がある)
◦ リフレクションが不要になる (場合がある) ◦ シグネチャがより直感的になる (場合がある) • ただし制約が強い 23
spec: generic methods for Go #77273 https://github.com/golang/go/issues/77273 24
25 https://github.com/golang/go/issues/77273#issuecomment-3962618141
おさらい: Goのジェネリクスの限界 (2) • ジェネリックなinterfaceのメソッドへの対応 が困難だったため ◦ 独自型のメソッドをジェネリクス対応するなら interfaceもジェネリクス対応しないといけなくなる ◦
ジェネリックなinterfaceのメソッド呼び出しを効率 的に実装できない 26
認識の変化 (1) • ジェネリックなメソッドは、interfaceに対し て実装されないとしても、コードの名前空間 を整理するのに有用である ◦ >Therefore methods are
useful for organizing code even if they don't ever implement an interface. 27
認識の変化 (2) • c(b(a(x))) よりも x.a().b().c() のほうが読み やすい ◦ そうですね
28
メソッドのジェネリクス • Go 1.27で実装予定 • 具体型のメソッドに型引数を渡せる ◦ interfaceのメソッドは引き続き未対応 29
夢: コレクション操作 • xs.Filter(...).Map(...) のようにジェネリック なコレクション操作を記述できる ◦ Filterは書けたけどMapが無理だった ▪ 任意の型に変わりうるため
◦ Filter(Map(xs, ...), ...) より読みやすいのでは 30
夢: Option・Result型 • structで実装すればメソッドチェーンできる ◦ Some(x).Map(...) ◦ None() とは書けなくて型引数が必須 •
if err != nil { ... } とどちらが読みやすいか ◦ Go wayからは外れる 31
夢: Webサーバーのパラメータ • 入力値のスキーマをstruct型で表現 • Hono/expressっぽいAPI ◦ app.POST("/blog", handlePostBlog) ◦
第2引数をジェネリックにできる 32
夢: パイプライン演算子 • g(f(x)) が x |> f |> g
みたいに書けるやつ ◦ Apply(x, f.Pipe(g)) • かっこいい ◦ 気をつけないとむしろ読みづらくなる ◦ いいインタフェースにしないと破滅しそう 33
34 DEMO (時間あれば)
所感 (1) • 関数がメソッドチェーンになることで見やす くなる (ことがある) ◦ 濫用すると逆に見づらい 35
所感 (2) • コンパイラの制約に阻まれることもある ◦ Claude Codeにパーサコンビネータの実装を生成して もらったけどinstantiation cycleエラーでビルドが通 らなかった
◦ Go 1.18から変わっていない制約 ▪ サイズが無限に大きくなりうる型を定義できない 36
タイトルに答える • 「メソッドのジェネリクスでGoの夢は広がる か?」 ◦ 広がるところもある ◦ メソッドのジェネリクス以外の制約に気をつける ◦ 濫用するとどんどんGo
wayから遠ざかる 37
まとめ • Go 1.27でメソッドのジェネリクスが実装さ れる ◦ これまではジェネリクスにできなかった • いい使い方を思いついたら自慢してください ◦
コンパイルエラーにならないなら 38
付録: デモ用のリポジトリ https://github.com/utgwkk/go127-generic s-dream 39
付録: VSCodeでHEADのgoを使う (1) $ go install golang.org/dl/gotip@latest $ gotip download
$ gotip install golang.org/dl/gotip@latest 40
付録: VSCodeでHEADのgoを使う (2) .vscode/settings.json に追記する { "go.alternateTools": { "go": "~/sdk/gotip/bin/go",
"gopls": "~/go/bin/gopls" } } 41