Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
range over funcのエラー処理
Search
MakKi
June 07, 2024
1
1.7k
range over funcのエラー処理
(Unofficial)Go Conference 2024 Pre Party
MakKi
June 07, 2024
Tweet
Share
More Decks by MakKi
See All by MakKi
Recap: An Operating System in Go
makki_d
1
99
XSLTで作るBrainfuck処理系
makki_d
0
280
眼鏡と視力についての誤解を解く
makki_d
0
140
標準ライブラリの動向とイテレータのパフォーマンス
makki_d
3
740
GoとテストとインプロセスDB
makki_d
3
640
君は古の言語M4を知っているか (LT)
makki_d
0
490
型パラメータが使えるようになったのでLINQを実装してみた
makki_d
2
1.5k
mallocしただけでメモリが確保できるって本当ですか?
makki_d
0
260
ホットリロードツールの作り方
makki_d
1
1.2k
Featured
See All Featured
Being A Developer After 40
akosma
91
590k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
140
34k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
A Modern Web Designer's Workflow
chriscoyier
697
190k
Building Adaptive Systems
keathley
44
2.9k
GitHub's CSS Performance
jonrohan
1032
470k
The Language of Interfaces
destraynor
162
25k
How to Think Like a Performance Engineer
csswizardry
28
2.3k
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円) 既刊もよろしく