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
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
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.8k
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.5k
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
180
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
16
3.7k
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
180
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
1.1k
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
140
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
220
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
130
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
460
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
450
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.3k
Featured
See All Featured
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
450
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
190
Done Done
chrislema
186
16k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
190
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.7k
My Coaching Mixtape
mlcsv
0
180
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
620
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
650
A Soul's Torment
seathinner
6
3.1k
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