17. 迭代器模式(Iterator)
17. 迭代器模式(Iterator)
问题:想统一遍历不同数据结构,不暴露内部实现。
核心:提供 next() 方法,依次返回元素直到结束。
class NumberIterator implements Iterator<number> {
#data: number[];
#index: number = 0;
constructor(data: number[]) { this.#data = data; }
next(): IteratorResult<number> {
if (this.#index < this.#data.length) {
return { value: this.#data[this.#index++], done: false };
}
return { value: undefined, done: true };
}
}
const iter = new NumberIterator([10, 20, 30]);
while (true) {
const result = iter.next();
if (result.done) break;
console.log(result.value);
}
// 10 → 20 → 30package iterator
import "fmt"
type Iterator[T any] struct {
data []T
cursor int
}
func NewIterator[T any](data []T) *Iterator[T] {
return &Iterator[T]{data: data}
}
func (it *Iterator[T]) Next() (T, bool) {
var zero T
if it.cursor >= len(it.data) {
return zero, false
}
val := it.data[it.cursor]
it.cursor++
return val, true
}
// 使用
// iter := NewIterator([]int{10, 20, 30})
// for {
// val, ok := iter.Next()
// if !ok { break }
// fmt.Println(val)
// }实战场景
- 数组、Map、Set 遍历:调用方不关心内部结构,只按统一协议逐个取值。
- 分页 API:后端数据按页返回时,迭代器可以隐藏 page token 和下一页请求逻辑。
- 数据库游标:大量数据不能一次性加载到内存,用 cursor 每次取一批或一条。
- 文件流读取:逐行读取日志、CSV、NDJSON,比一次性读完整文件更省内存。
- 树结构遍历:菜单、组织架构、AST 可以提供深度优先或广度优先迭代器。
- 生成器流水线:数据清洗、过滤、转换一步步 yield,适合处理大列表或无限序列。
- UI 虚拟列表:只迭代当前可见范围的数据,避免渲染所有节点。
- 消息消费:队列消费者不断取下一条消息,直到被停止或没有更多消息。
- 搜索结果聚合:从多个来源按统一迭代接口取结果,再合并、去重、排序。
- 测试用例生成:参数组合很多时,用迭代器按需生成用例,不提前构造巨大数组。