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
パッケージ設計の黒魔術/Kyoto.go#63
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
kadota kyohei
August 31, 2025
Programming
580
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
パッケージ設計の黒魔術/Kyoto.go#63
黒魔術の話です
kadota kyohei
August 31, 2025
More Decks by kadota kyohei
See All by kadota kyohei
govulncheckの紹介/govulncheck-intro
lufia
1
70
最近変わった開発時のあれこれ/features-of-recent-go
lufia
0
970
GCPとGoの話/gcpug-osaka-6
lufia
0
530
調べながらGCPやってみた話/gcpug-osaka-3
lufia
1
540
REST is not only (web) API interface
lufia
1
1k
Go駆動開発で超速Pushエンジンを作った話
lufia
19
7.5k
Other Decks in Programming
See All in Programming
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
510
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.5k
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
160
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
160
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
200
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.3k
Android CLI
fornewid
0
200
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
130
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
280
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
9
4.3k
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
140
Featured
See All Featured
A Soul's Torment
seathinner
6
3.1k
Everyday Curiosity
cassininazir
0
270
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Rails Girls Zürich Keynote
gr2m
96
14k
Building the Perfect Custom Keyboard
takai
2
830
The SEO Collaboration Effect
kristinabergwall1
1
510
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
650
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Transcript
パッケージ設計の黒魔術 id:lufiabb / @plan9user 2025/08/31 Kyoto.go #63 オフラインLT会 1
今日の話 • reflect.StructField.Offset • go build -overlay=[file] • ovechkin-dm/go-dyno 2
3 StructField.Offset
Offset • reflectで構造体フィールドを探すとき • 名前やインデックスはよくある ◦ reflect.Value.FieldByIndex ◦ reflect.Value.FieldByName •
メモリ上のオフセットでも特定できる ◦ reflect.StructFieldにOffsetフィールドがある 4
Offset type User struct { ID int Active bool Name
string } 5 ID Offset 0 未使用(アラインメント) Active Name Offset 8 Offset 16
使い方 p0 := reflect.ValueOf(&u).Pointer() p1 := reflect.ValueOf(&u.Active).Pointer() off := p1
- p0 for _, f := range reflect.VisibleFields(reflect.TypeOf(u)) { if f.Offset == off { fmt.Println(f.Name) // Output: Active } } 6
何が嬉しいの 型パラメータと一緒に使うと型を残せる func Assert[T, F any](u T, p *F) Equaler[F]
Assert(u, &u.Name).Equal(“example”) 7 型を間違えると ビルドエラー
よくあるやつ type User struct { ID int `json:”id” validate:”qte=1”` Name
string `json:”name” validate:”required”` } 文字列で指示するものは同じ問題が起きがち 8 長くなりがち typoしても気づかない
バリデーションにも活かせる validation.ValidateStruct( validation.Field(&s.ID, validation.Min(1)), validation.Field(&s.Name, validation.Required()), ) 9 改行できる 型情報が活かせる
10 -overlay=[file]
overlayオプション • go build -overlay=[file] ◦ tenntenn/testtimeで知った • 特定のファイルをビルド時に置き換える 11
overlay.json { “Replace”: { “変更したいファイルパス ”: “変更後のファイルパス ” } }
go build -overlay=overlay.json 12
何が起きるのか • ビルド時に動的なファイル置換が起きる • osやruntimeのファイルも変えられる • 実質的になんでもできる ◦ 当然Goのバージョンが上がったら壊れる(こともある) 13
実用例 scope := plug.CurrentScope() defer scope.Delete() key := plug.Func("os.Getpid", os.Getpid)
plug.Set(scope, key, func() int { return 1 }) 14
実用例 key := plug.Func("os.Getpid", os.Getpid) ソースコードが分かれば一部の関数だけ変更するのは簡単 静的解析で overlayファイルを自動生成できる ※ とても行儀は悪いのでテスト用途に留めましょう
15 静的解析でパッケージの ソースコードが取れる Funcをマーカーとし て静的解析で探す
16 go-dyno
go-dyno • ovechkin-dm/go-dyno • 動的にインターフェイスを実装するライブラリ ◦ 普通の方法ではできない 17
go-dyno • ovechkin-dm/go-dyno • 動的にインターフェイスを実装するライブラリ ◦ 普通の方法ではできない 18
普通の方法 • 構造体フィールドを動的に生成できる • 関数もある程度は動的に生成できる • メソッドは作れない ◦ runtimeやunsafeにもそんなものはない 19
go-dynoの使用例 iface, err := dyno.Dynamic[io.Reader](handleMethod) func handleMethod( method reflect.Method, args
[]reflect.Value, ) []reflect.Value { return nil } 20 メソッド名が取れる 引数も取れる 実装したいインターフェイス
go-dyno • インターフェイスをモックしたければコード生 成しかない(と思っていた) ◦ コード生成は遅いしコンフリクトも多い • go-dynoで選択肢が広がった • GoCon
2025でkaramaruさんが話すらしい 21
まとめ • ライブラリデザインに使えそうな黒魔術を3つ 紹介しました • デザインの参考になれば嬉しいです 22