每日一Lua(5)-迭代器与泛型for
2013-02-25 20:52
281 查看
所谓迭代器就是一种可以遍历一种集合中所有元素的机制。在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 iterator
function values(t)
local i=0;
return function() i=i+1;return t[i] end
end
t={-1,-1,-1,-1,-1}
--create iterator
iter=values(t)
while true do
local element=iter()
if element==nil then break end
print(element)
end
程序中定义的迭代器就是前面说过的closure。
这个closure通常设计到两个函数:closure本身和一个用于创建该closure的工厂(factory)函数。
用泛型for来实现则更简单,因为它就是为这个而活的。
--for style
for element in values(t) do
print(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) do
print(i,v)
end
for i,v in ipairs(b) do
print(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,所以直接跳出循环不输出任何值。
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 iterator
function values(t)
local i=0;
return function() i=i+1;return t[i] end
end
t={-1,-1,-1,-1,-1}
--create iterator
iter=values(t)
while true do
local element=iter()
if element==nil then break end
print(element)
end
程序中定义的迭代器就是前面说过的closure。
这个closure通常设计到两个函数:closure本身和一个用于创建该closure的工厂(factory)函数。
用泛型for来实现则更简单,因为它就是为这个而活的。
--for style
for element in values(t) do
print(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) do
print(i,v)
end
for i,v in ipairs(b) do
print(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,所以直接跳出循环不输出任何值。
相关文章推荐
- 每日一Lua(5)-迭代器与泛型for
- Lua_泛型for与迭代器
- 六、Lua中的迭代器与泛型for
- Lua笔记7-迭代器和泛型for
- lua迭代器与泛型for
- 利用lua中的closure来实现lua迭代器以及用泛型for实现lua的无状态迭代器
- Lua迭代器和泛型for)
- lua语言-《lua程序设计》6~7章函数和迭代器与泛型for
- 二、Lua迭代器与泛型for
- Step By Step(Lua迭代器和泛型for)
- Lua中的迭代器和泛型for介绍
- Step By Step(Lua迭代器和泛型for)
- Step By Step(Lua迭代器和泛型for)
- lua中的迭代器与泛型for
- Lua 迭代器与泛型for
- Lua学习笔记 第七章 迭代器与泛型for
- Lua学习笔记(七):迭代器与泛型for
- 深入解读Lua中迭代器与泛型for的使用
- Lua中的迭代器和泛型for实例
- lua中的泛型for 和迭代器