迭代器
让我们回到无聊的计数实例:
echo("Counting to ten: ")
for i in countup(1, 10):
echo($i)
可以写一个conutup过程支持这个循环吗?让我们试试
proc countup(a, b: int): int =
var res = a
while res <= b:
return res
inc(res)
然而,这不工作。问题是这个过程应该不仅return,而且需要返回和continue在一个迭代器完成之后。这个返回和继续称为一个yield语句。现在剩下的唯一要做的事情是用iterator替换proc关键字,这是我们的第一个迭代器:
iterator countup(a, b: int): int =
var res = a
while res <= b:
yield res
inc(res)
迭代器看起来与过程很像。但这存在几点很大的不同:
- 迭代器只能被循环调用。
- 迭代器不能包含return语句,过程不能包含yield语句。
- 迭代器没有隐含的result变量。
- 迭代器不支持递归。
- 迭代器不能提前声明,因为编译器必须能够内联一个迭代器(这个限制将会在未来版本的编译器中消失)。
然而,你也可以使用一个封闭的迭代器来获得一组不同的限制。迭代器可以有相同的名字和参数作为一个过程,基本上它们有自己的命名空间。因此它常见的做法是积累过程中相同名字的迭代器的结果,并将它们作为一个序列返回,例如strutils模块的划分。