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
range over funcのエラー処理
Search
MakKi
June 07, 2024
1
1.6k
range over funcのエラー処理
(Unofficial)Go Conference 2024 Pre Party
MakKi
June 07, 2024
Tweet
Share
More Decks by MakKi
See All by MakKi
眼鏡と視力についての誤解を解く
makki_d
0
110
標準ライブラリの動向とイテレータのパフォーマンス
makki_d
3
650
GoとテストとインプロセスDB
makki_d
3
560
君は古の言語M4を知っているか (LT)
makki_d
0
390
型パラメータが使えるようになったのでLINQを実装してみた
makki_d
2
1.4k
mallocしただけでメモリが確保できるって本当ですか?
makki_d
0
220
ホットリロードツールの作り方
makki_d
0
1.1k
JavaプログラムをGoに移植するためのテクニック――継承と例外
makki_d
1
1.7k
JavaプログラムをGoに移植するためのテクニック――継承と例外
makki_d
4
4.2k
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
4
500
Embracing the Ebb and Flow
colly
85
4.6k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
102
19k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
8
720
The Invisible Side of Design
smashingmag
299
50k
KATA
mclloyd
29
14k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
How to train your dragon (web standard)
notwaldorf
91
5.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
30
1.1k
Practical Orchestrator
shlominoach
186
10k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Transcript
range over funcの エラー処理 Go Conference 2024 Pre Party
自己紹介 • MakKi (牧内 大輔) ◦ • KLab株式会社 ◦
オンライン対戦の通信基盤を Goで実装 ◦ github.com/KLab/wsnet2 • 過去の発表 ◦ Goとテストとインプロセス DB ◦ 型パラメータが使えるようになったので LINQを実装してみた ◦ ホットリロードツールの作り方 ◦ … makiuchi-d @makki_d
range over funcとは • Go 1.22 で GOEXPERIMENT入り • for文のrangeに関数を渡せる
◦ func(yield func() bool) ◦ func(yield func(V) bool) ◦ func(yield func(K, V) bool) • yieldした回数だけループが回る ◦ breakするとyieldがfalse ▪ それ以降yieldするとpanic func Three(yield func(int) bool) { if !yield(1) { return } if !yield(2) { return } if !yield(3) { return } } func main() { for n := range Three { fmt.Println(n) } // Output: // 1 // 2 // 3 } https://go.dev/play/p/HguOV9bxf59
関数内でエラー発生 • 呼び出し側(forループ)に errorの値をどうにかして伝えたい • yieldを呼ぶか終了するかしかできない ◦ yield: errorを渡せない ◦
終了: 正常終了と見分けがつかない いまいちな方法〜いいかんじの方法を 4パターン考えてきました func Three(yield func(int) bool) { if !yield(1) { return } err := fmt.Errorf("Error!") } func main() { for n := range Three { fmt.Println(n) } } どうやって伝える?
1. panicする? • forループ側にpanicが伝搬 ◦ recoverすればエラーを取り出せる • 利用者にrecoverさせるのは不親切 func Three(yield
func(int) bool) { if !yield(1) { return } err := fmt.Errorf("Error!") panic(err) } func main() { var err error func() { defer func() { err, _ = recover().(error) }() for n := range Three { fmt.Println(n) } }() if err != nil { fmt.Println(err) } } https://go.dev/play/p/7h-IXsacSb1
2. 受け取り用ポインタ? • error型変数を用意 • errorポインタを受け取り、関数を返す ◦ ポインタの先にerrorを設定して終了する関数 • ループを抜けてからnullチェック
• 実装が複雑 func Three(ep *error) func(func(int) bool) { return func(yield func(int) bool) { if !yield(1) { return } err := fmt.Errorf("Error!") *ep = err } } func main() { var err error for n := range Three(&err) { fmt.Println(n) } if err != nil { fmt.Println(err) } } https://go.dev/play/p/B-fSKCH88AW
3. structに詰めてyield? • 値とerrorをまとめたstructを定義 • そのstructに詰めてyieldに渡す • ループ内でstructの中のerrorをチェック • structの定義が必要
• 毎回詰めたり取り出したり面倒 type ValErr struct { Val int Err error } func Three(yield func(ValErr) bool) { if !yield(ValErr{1, nil}) { return } err := fmt.Errorf("Error!") yield(ValErr{0, err}) } func main() { for ev := range Three { if ev.Err != nil { fmt.Println(ev.Err) break } fmt.Println(ev.Val) } } https://go.dev/play/p/ff0FTnCnfj7
4. 2値のyield! • yield func(K, V) bool • K, Vともにどんな型でもOK
◦ mapのようなcomparable制約はない • 値とerrorをyieldに渡す ◦ for文側で値とerrorを受け取れる • Goとしてよく見る形 • 実装もシンプル ◦ ただしKey-Valueを返すときはKをstructに…… func Three(yield func(int, error) bool) { if !yield(1, nil) { return } err := fmt.Errorf("Error!") yield(0, err) } func main() { for n, err := range Three { if err != nil { fmt.Println(err) break } fmt.Println(n) } } https://go.dev/play/p/0VNRQSv7ELe
まとめ range for funcでエラーを伝えたいときは func(yield func(V, error) bool) の形で関数を実装すると綺麗!
宣伝 技術書典16 KLab Tech Book Vol.13 電子版0円(電子+紙 500円) 既刊もよろしく