The Go gopher was designed by Renée French.
The gopher stickers was made by Takuya Ueda.
Licensed under the Creative Commons 3.0 Attributions license.
まずはイテレータ
(range over func)の
仕様を学ぼう
2024/09/24
Goのイテレータ深堀りNight
https://tenn.in/iternight
1
イテレータ( range over func)
1
2
3
seq0 := func(yield func() bool) {}
for range seq0 {}
seq1 := func(yield func(X) bool) {}
for x := range seq1 {}
seq2 := func(yield func(X, Y) bool) {}
for x, y := range seq2 {}
for range文に関数が指定できるようになった
Slide 7
Slide 7 text
range over funcと他のrange over
対象
こ
れ
ま
で
関
数
振る舞い
[N]E, *[N]E, []E,
map[K]V, string,
chan E, <-chan E,
N
func(func() bool)
func(func(X) bool)
func(func(X, Y) bool)
型ごとに決められている
例:先頭から順に
関数によって実装する
例:後方から、深さ優先探索
イテレーションの仕方が自由になった
Slide 8
Slide 8 text
重要な3つの仕様
1
for range文に指定した関数が
1度だけ実行される
2
yield関数を呼ぶと
for文のボディに処理が移る
3
for range文が途中で終了すると
yield関数がfalseを返す
for range func
call
for range func
yield
for range func
false
break return
Slide 9
Slide 9 text
例:アルファベット列の生成
func Alphabet(yield func(rune) bool) {
for c := 'A'; c <= 'Z'; c++ { // 'A', 'B', 'C', …
if !yield(c) { return }
}
}
func usage() {
// ABC
for c := range Alphabet {
fmt.Printf("%c", c)
if c == 'C' { break }
}
}
Slide 10
Slide 10 text
標準ライブラリの変更点
1
2
type Seq[V any] func(yield func(V) bool)
type Seq2[K, V any] func(yield func(K, V) bool)
iterパッケージと iter.Seq型とiter.Seq2型が導入された
※ iter.Pull関数とiter.Pull2関数についてはeihighさんにお任せします!
Slide 11
Slide 11 text
例:マップ関数
func Map[X, Y any](seq iter.Seq[X], f func(X) Y) iter.Seq[Y] {
return func(yield func(Y) bool) {
for x := range seq { if !yield(f(x)) { break } }
}
}
func usage() {
seq := Map(slices.Values([]int{10, 20}), func(x int) string {
return fmt.Sprintf("0x%x", x)
})
// 0xa
// 0x14
for v := range seq { fmt.Println(v) }
}