迭代器
让我们回到简单的计数示例:
- echo "Counting to ten: "
- for i in countup(1, 10):
- echo i
一个 countup 过程可以支持这个循环吗?让我们试试:
- proc countup(a, b: int): int =
- var res = a
- while res <= b:
- return res
- inc(res)
这不行,问题在于过程不应当只 return ,但是迭代器后的return和 continue 已经完成。这 return and continue 叫做 yield 语句。现在只剩下用 iterator 替换 proc 关键字, 它来了——我们的第一个迭代器:
- iterator countup(a, b: int): int =
- var res = a
- while res <= b:
- yield res
- inc(res)
迭代器看起来像过程,但有几点重要的差异:
- 迭代器只能从循环中调用。
- 迭代器不能包含 return 语句(过程不能包含 yield 语句)。
- 迭代器没有隐式 result 变量。
- 迭代器不支持递归。
- 迭代器不能前向声明,因为编译器必须能够内联迭代器。(这个限制将在编译器的未来版本中消失。)
你也可以用 closure 迭代器得到一个不同的限制集合。详见 一等迭代器 。 迭代器可以和过程有同样的名字和形参,因为它们有自己的命名空间。 因此,通常的做法是将迭代器包装在同名的proc中,这些迭代器会累积结果并将其作为序列返回, 像 strutils模块 中的 split 。