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
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
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
range over funcのエラー処理
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
MakKi
June 07, 2024
1.9k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
range over funcのエラー処理
(Unofficial)Go Conference 2024 Pre Party
MakKi
June 07, 2024
More Decks by MakKi
See All by MakKi
テストだけじゃない!インプロセスDBで生まれるGoらしさ
makki_d
0
56
テストだけじゃない!インプロセスDBで生まれるGoらしさ
makki_d
0
72
SQLだけでマイグレーションしたい!
makki_d
0
1.4k
Recap: An Operating System in Go
makki_d
2
190
XSLTで作るBrainfuck処理系
makki_d
0
440
眼鏡と視力についての誤解を解く
makki_d
0
240
標準ライブラリの動向とイテレータのパフォーマンス
makki_d
3
790
GoとテストとインプロセスDB
makki_d
3
710
君は古の言語M4を知っているか (LT)
makki_d
0
590
Featured
See All Featured
Balancing Empowerment & Direction
lara
6
1.3k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
It's Worth the Effort
3n
188
29k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
65k
Visualization
eitanlees
152
17k
Google's AI Overviews - The New Search
badams
0
1.6k
The Limits of Empathy - UXLibs8
cassininazir
1
650
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
680
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
270
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
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円) 既刊もよろしく