Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
パッケージ設計の黒魔術/Kyoto.go#63
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
kadota kyohei
August 31, 2025
Programming
590
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
83
最近変わった開発時のあれこれ/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
1.1k
Go駆動開発で超速Pushエンジンを作った話
lufia
19
7.5k
Other Decks in Programming
See All in Programming
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
690
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
130
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
0
250
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
220
信頼性の目標を誰も求めてない
shubox
0
500
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
業務時間外もAIに働いてもらう話
colorful12
3
10k
アクセシビリティから考える情報設計
high_g_engineer
0
320
Family mrubyの進捗
kishima
1
100
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
640
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
110
Featured
See All Featured
We Are The Robots
honzajavorek
0
350
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
How to Think Like a Performance Engineer
csswizardry
28
2.8k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
The SEO identity crisis: Don't let AI make you average
varn
0
550
Making the Leap to Tech Lead
cromwellryan
135
10k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
AI: The stuff that nobody shows you
jnunemaker
PRO
9
980
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Designing for Performance
lara
611
70k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
490
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
450
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