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

本文详细介绍了Lua中迭代器的概念,并通过实例展示了如何使用迭代器遍历集合中的元素,包括简单迭代器、泛型for迭代器以及无状态迭代器的应用。同时,文章深入探讨了迭代器在Lua中的实现方式,以及如何利用迭代器简化代码结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

所谓迭代器就是一种可以遍历一种集合中所有元素的机制。在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,所以直接跳出循环不输出任何值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值