Go1.23 Iterators 迭代器

建议点击 查看原文 查看最新内容。

原文链接: https://typonotes.com/posts/2025/05/22/go1.23-iterators/

在 Go1.23 新引入了一个标准包 迭代器 Iterator 。 可以返回一个 可迭代对象 - 函数该对象 接受一个 回调函数 - yield

标准包 iter 中包含以下两个类型 Seq, Seq2。 二者都返回了一个 生成器函数 yield function

1
2
3
4
type (
    Seq[V any]     func(yield func(V) bool)
    Seq2[K, V any] func(yield func(K, V) bool)
)

Seq2 的命名方式看起来很奇怪, 感觉不太符合 golang 的命名习惯。 这里推测 2 表示接受的回调有两个参数。 func(yield func(K, V) bool)

1. 标准库的迭代器

截至 go1.24 , 目前已经有 4个 标准包支持返回迭代器了。

这个没什么好说的, 直接看文档就行了。

2. 迭代器对象的使用

迭代器的两种使用方式 回调函数for 循环。

  1. 使用 回调函数 时, 可以通过 return false 提前终止遍历。

  2. 使用 for 循环时

    • Seq 返回的对象是 , 类似于 for _, v := range []int{1,2,3} 中的 v
    • Seq2 返回的对象是 键、值。 普通的 for 循环类似。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Seq
l := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
it1 := slices.Values(l)

for v := range it1 {  // Seq 返回的是 v
    println(v)
}


call1 := func(v int) bool {
    if v > 5 {
        return false  // false 提前退出
    }
    fmt.Println(v)
    return true
}
it1(call1) // 1,2,3,4,5



// Seq2
m := map[string]string{
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
}

it2 := maps.All(m)
for k, v := range it2 {  // Seq2 返回的是 k, v
    println(k, v)
}

call2 := func(k, v string) bool {
    if k == "key2" {
        return false
    }

    println(k, v)
    return true
}

it2(call2)

3. 第三类生成器函数

Go1.23 的 Release Notes 中提到的 无参数迭代对象, 并没有在标准包中找到。

1
2
3
4
5
func(func() bool) // 无参数


func(func(K) bool)  // Seq: 1 参数
func(func(K, V) bool) // Seq2: 2 参数

目前我这边没想到有什么使用场景, 从语法上来看, 配合 柯里化函数通道 等手段, 还是有操作性的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// currylock 返回了一个自身计数的迭代器
func currylock() func() bool {

    n := 3
    i := 1
    return func() bool {
        println(i, "<", n)
        i++
        if i > n {
            return false
        }
        return true
    }
}

func seq0() {
    it0 := currylock()

    for it0() {  // 调用的时候就像死循环。
                 // 其实感觉有没什么特别的。
                 // 就是 `for bool {}` 的模式。
    }
    // 1 < 3
    // 2 < 3
    // 3 < 3
}

4. 扩展阅读

  1. Range Over Function Types - https://go.dev/blog/range-functions