主要观点:Golang 的迭代器是每次“产出”一个结果的函数,替代一次性计算并返回所有结果。for
循环中range
表达式为迭代器时,会为迭代器返回的每个值执行一次。迭代器很有用,能避免一次性生成和处理整个切片,减少内存分配和浪费。
关键信息:
- 迭代器函数签名:
func (yield func(Item) bool)
,通过yield
函数产出值,全部产出后返回表示迭代完成。 - 单值迭代器
iter.Seq
:如func Items() iter.Seq[Item]
,返回一个可迭代的Item
序列。 - 双值迭代器
iter.Seq2
:签名为func (int, Item) bool
,可同时产出索引和值,如func Items() iter.Seq2[int, Item]
。 - 处理错误:可通过
iter.Seq2
返回值和错误,调用者需检查错误。 - 清理资源:
yield
返回false
可作为清理资源的信号。 - 组合迭代器:可编写接受和返回迭代器的函数,如
func PrintAll[V any](seq iter.Seq[V])
。 - 与通道对比:迭代器在避免并发问题和处理循环提前退出方面更友好,而通道在并发编程中有其他优势。
- 标准库变化:
slices
和maps
包新增返回迭代器的函数,如slices.All
、slices.Values
等。
重要细节:
- 示例中
Items
函数通过生成Item
切片并在for
循环中通过yield
产出每个值来实现迭代器。 - 当需要索引时,双值迭代器可满足需求,如
for i, v := range Items()
。 - 迭代器在处理读取
io.Reader
或bufio.Scanner
等可能出错的情况时,可通过返回值和错误来处理。 - 标准库中
for i, v := range slices.All(s)
可遍历切片的索引和值,for v := range slices.Values(s)
可只遍历值。对于map
也有类似的遍历函数。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。