上一篇我们介绍了,可以使用for循环来完成迭代器的调用,十分简洁。
那么,具体这for循环做了什么呢?我当然没有去看源码,我只是看书而已。
资料来源于《Lua程序设计》第二版,如果这本书的内容没有错的话,那么,本篇文章理论上也不会有错~
1.返回两个值的迭代器
pairs是能遍历table的key和value的,而我们之前写的dieDaiQi函数只能返回value。
所以,我们要改改dieDaiQi函数,如下:
复制代码 代码如下:
function dieDaiQi(t)
local i = 0;
return function()
i = i + 1;
if i > #t then
return nil;
end
return i, t[i];
end
end
当然了,这不是一个安全的迭代器,我们假设table中没有nil值。
至于为什么要有一个if i > #t的判断,待会会说到。
使用如下方式调用迭代器:
复制代码 代码如下:
local t = {"fdsd", "445", "9999"};
for k, v in dieDaiQi(t) do
print(k .. "," .. v);
end
输出结果如下:
复制代码 代码如下:
[LUA-print] 1,fdsd
[LUA-print] 2,445
[LUA-print] 3,9999
2.for .. in .. do的真面目
【for k, v in dieDaiQi(t) do end】这段代码实际上等价于以下代码:
复制代码 代码如下:
do
local _f, _s, _var = dieDaiQi(t);
while true do
local k, v = _f(_s, _var);
_var = k;
if _var == nil then
break;
end
print(k .. "," .. v);
end
end
是不是很复杂?其实它和我们之前第一次调用迭代器的代码很像,我们先删掉复杂的部分,代码变成如下:
复制代码 代码如下:
do
local _f = dieDaiQi(t);
while true do
local k, v = _f();
if k == nil then
break;
end
print(k .. "," .. v);
end
end
试试运行这段代码,结果如下:
复制代码 代码如下:
[LUA-print] 1,fdsd
[LUA-print] 2,445
[LUA-print] 3,9999
和直接使用for in循环是一样的结果。
实际上,我说的这些都是废话,因为我们之前就已经说,for in循环就是用来简化迭代器的调用的,所以当然是一样的结果。
3.迭代器函数、恒定状态、控制变量初值
我们来看看for in真面目的第一句代码:local _f, _s, _var = dieDaiQi(t);
三个返回值分别代表迭代器函数(_f)、恒定状态(_s)、控制变量初值(_var)。
迭代器函数:就不用解释了,就是我们的dieDaiQi返回的闭合函数。
恒定状态:其实就是一个变量,这个变量一直不变,所以称之为恒定。
控制变量初值:和恒定相对于的,这是一个会不断改变的变量。
因为我本人没有实际使用过这种特性,所以没法举出实际的例子,只能从理论上去解释。
1.比如我们的dieDaiQi函数,它只有一个返回值,就是那个闭合函数,所以,_s和_var都是nil。
2.接着调用local k, v = _f(_s, _var); 这实际上就是调用了闭合函数,并且将恒定值和变量值都作为参数传递进去。
3.Lua的函数是很自由的,即使_f函数本身没有参数,也可以传参数进去,不会影响什么,所以,两个nil值传进去了,没有任何事情发生,就像是直接调用_f()一样。
4.再下一句代码:_var = k; 这是把闭合函数(_f)的第一个返回值保存起来,因为每次调用闭合函数(_f)返回值都是下一个迭代值,所以_var每次都是不一样的值。
5.如果_var的值为nil,则停止循环,结束迭代。
因此,我们编写迭代器的时候,迭代结束的方式就是让第一个返回值为nil。
那么,如果我们让dieDaiQi函数返回恒定状态和控制变量初值,又是什么样的情况呢?
代码如下:
复制代码 代码如下:
function dieDaiQi(t)
local i = 0;
return function(s, var)
i = i + 1;
if i > #t then
return nil;
end
print("恒定值=" .. s .. ", 变量值=" .. var)
return i, t[i];
end, 10, 0
end
留意一下,dieDaiQi函数现在会返回三个参数,后面的10和0分别就是恒定状态和控制变量初值。
同时,闭合函数也多了两个参数:s和var。
于是,我们再次用for循环遍历迭代器:
复制代码 代码如下:
for k, v in dieDaiQi(t) do
print(k .. "," .. v);
end
输出结果如下:
复制代码 代码如下:
[LUA-print] 恒定值=10, 变量值=0
[LUA-print] 1,fdsd
[LUA-print] 恒定值=10, 变量值=1
[LUA-print] 2,445
[LUA-print] 恒定值=10, 变量值=2
[LUA-print] 3,9999
恒定值自然是一直不变的,而变量值在每一次调用了闭合函数之后,就会赋值为k的值,所以变量值一直按着table的key值在变化。
可能一时有点混乱,不过,只要对照着for .. in .. do .. end对应的实现代码,就很好理解了。
4.结束
终于写完了,我快撑不住了,一晚上写两篇文章,可够折腾的。
现在眼睛都是花的…我不知道我还能坚持多少个晚上…
幸好学习的内容会越来越难,这样我就没法一个晚上就理解透彻,也就没法每晚写一篇教程了~
太好了,呵呵。(小若:想偷懒就偷懒吧,说这么多做什么)
Lua,for循环,迭代器
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 郑秀文.2024-Best.Concert.Live【华纳】【FLAC分轨】
- 《Pax Dei》配置要求一览
- 《过山车之心2》存档位置介绍
- 《三国志8 REMAKE》评测:自定义的三国演义
- 群星《少年白马醉春风 网剧OST原声专辑》[320K/MP3][117.05MB]
- 群星《少年白马醉春风 网剧OST原声专辑》[FLAC/分轨][621.04MB]
- 《魏佳艺5CD合集》[WAV分轨][3.8G]
- CSGO职业选手donk怎么样 2024最新donk个人资料介绍
- CSGO职业选手NiKo怎么样 2024最新Niko个人资料介绍
- 剑网3丝路风语PVE焚影怎么打 丝路风语PVE焚影圣诀手法配装攻略
- [老虎魚古典名盘]心碎SACD浪漫小提琴之声[DSF]
- Queen(皇后乐队)《GreatestHitsII》[SACD-DSF]
- 伤感绝唱《凄凉的爱》黑胶3CD[WAV+CUE]
- 老外盛赞《剑星》新战衣:还是韩厂了解玩家胃口!
- 玩家认为不用纠结游玩方式:享受才是第一 你同意吗?