每日一Lua(5)-迭代器与泛型for

来源:互联网 发布:windows屏保 编辑:程序博客网 时间:2024/06/14 13:20

所谓迭代器就是一种可以遍历一种集合中所有元素的机制。在lua中,迭代器通常表示为函数,每调用依次函数就返回集合中的下一个元素。

1.最简单的迭代器

首先来看c++中的迭代器,输出vector中的所有元素。

#include <iostream>#include <vector>using namespace std;int main(){    vector<int> ivec(5,-1);    for (vector<int>::iterator iter = ivec.begin(); iter!= ivec.end(); ++iter)       cout<<*iter<<endl;return 1;}

下面用lua来实现。

--declare an iteratorfunction values(t)local i=0;return function() i=i+1;return t[i] endendt={-1,-1,-1,-1,-1}--create iteratoriter=values(t)while true dolocal element=iter()if element==nil then break endprint(element)end



程序中定义的迭代器就是前面说过的closure。

这个closure通常设计到两个函数:closure本身和一个用于创建该closure的工厂(factory)函数。


用泛型for来实现则更简单,因为它就是为这个而活的。

--for stylefor element in values(t) doprint(element)end

效果是一样的。

2.泛型for

前面如果要使用迭代器的话就一定要创建一个closure,泛型for的话就不需要,实际上泛型for保存着三个值:一个迭代器函数,一个恒定状态和一个控制变量。

看之前的一个泛型for例子:

days = {"Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"}for k,v in pairs(days) do print(k..":"..v) end


通常泛型for的语法如下:

for <var-list> in <exp-list> do      <body>end

其中 <var-list>是一个或多个变量名的列表,以逗号分隔;<exp-list>是一个或多个表达式的列表,同样以逗号分隔,通常表达式列表只有一个元素,即一句对迭代器工厂的调用。

变量列表的第一个元素称为“控制变量”,当为nil的时候循环结束。

for做的第一件事就是对in后面的表达式求值,这些表达式应该返回三个值供for保存:迭代器函数、恒定状态和控制变量的初值。这类似于一个多元素的赋值。


3.无状态迭代器

指的是自身不保存任何状态的迭代器。

在每此迭代中,for循环都会用恒定状态和控制变量来调用迭代其函数,一个无状态的迭代器可以根据这两个值为下一次迭代生产下一个元素。

ipairs就是这样的迭代器。

a={"one","two","three"}b={[2]="four",[3]="five",[4]="six"}for i,v in ipairs(a) doprint(i,v)endfor i,v in ipairs(b) doprint(i,v)end


结果显示只打印a,而b没有打印。

在这里迭代的状态就是要遍历的table及当前的索引值。

lua在调用for循环的ipairs(a)时,会获得3个值:迭代器iter、恒定状态a和控制变量的初值0,然后调用iter(a,0),得到1,a[1],在第二次迭代中,继续调用iter(a,1),

得到2,a[2],以此类推。

在遍历b的时候,当key=1时候value就是nil,所以直接跳出循环不输出任何值。


原创粉丝点击