Lua iterator and generic for

简介:
lua有两种循环的用法
1.  数字递增用法
> for i=1,10,3 do
>> print(i)
>> end
1
4
7
10


2. generic for用法
不写步长step则默认是1.
> t = {"hello","nihao",nil,"yes"}
> for k,v in ipairs(t) do
>>   print("k:" .. k .. " v:" .. v) 
>> end
k:1 v:hello
k:2 v:nihao

使用table.pack将...变量参数打包成sequence表以及n存储sequences个数.
> c = table.pack("he","hello",nil,"a ")
> for i=1, c.n do
print(c[i])
end
he
hello
nil
a

其他常用的generic for函数
Despite its apparent simplicity, the generic for is powerful. With proper
iterators, we can traverse almost anything in a readable fashion. The standard
libraries provide several iterators, which allow us to iterate over 
the lines of a file (io.lines), 
the pairs of a table (pairs), 
the entries of a sequence (ipairs), 
the words of a string (string.gmatch), 
and so on.

在没有generic for函数前的自定义循环用法, 使用factory 函数封装non-local变量和iterator函数(匿名函数), 多次调用iterator函数, 变更non-local变量的值来达到循环的目的. 例如 : 
> function factory(t)  -- 工厂函数, 返回一个匿名函数
>>   local i = 0  -- 封装一个本地变量
>>   return function () i = i+1; return t[i] end  把上层本地变量引入这个匿名函数(后面用它做循环)
>> end
> tbl = {10,20,30}
> iterator = factory(tbl)  -- 使用工厂函数生成一个循环函数
> while true do
>>   local element = iterator()
>>   if element == nil then break end
>>   print (element)
>> end
10
20
30


直接使用generic for : 
> for element in factory(tbl) do
>>   print (element)
>> end
10
20
30

generic for 的语法  : 
for <var-list> in <exp-list> do
  <body>
end

解释 : 
<var-list> 是1个或多个变量名, 逗号隔开, 不需要事先定义. 列表中的第一个变量为控制变量.
<exp-list> 是一个或多个表达式, 逗号隔开.
Lua处理generic for语法的方法和顺序.
1. 首先运行exp-list中的表达式, 把所有表达式的返回值转成3个返回值, 注意如果其中有返回多值的函数, 最后可能只用第一个返回值. 例如.
> function x(...) return ... end
> = x(1,2,3)
1       2       3
> =x(1,2,3),4
1       4
> a,b,c=x(1,2,3),4  -- 函数后面还有其他变量或表达式时, 取第一个返回值.
> = a,b,c
1       4       nil
> a,b,c = 4,x(1,2,3)  -- 函数在最后一位时, 返回多值
> = a,b,c
4       1       2
> a,b,c = 4,(x(1,2,3))  -- 函数外加括号, 强制取第一个返回值
> = a,b,c
4       1       nil

如果exp-list中有多个表达式, 则需要考虑以上情况, 不管怎么样, 第一次运行这些表达式的结果会转换成3个值, 多则废弃多的, 少则末尾以nil填补.
这三个值分别代表iterator function(使用_f表示), invariant state (使用_s表示) , initial value for the control variable (使用_var表示) .
2. 第二步则调用iterator函数, 并把结果赋予给var-list的各个变量.
var_1, ..., var_n = _f(_s, _var)
_var = var_1
然后判断var_1是否为nil, 如果为nil则退出循环, 如果不为nil则继续调用_f(_s, _var);
所以以下两种用法实际上是同样的效果 :
for var_1, ..., var_n in <exp-list> do <block> end

等同于
do 
local _f, _s, _var = <exp-list>
while true do
  local var_1, ..., var_n = _f(_s, _var)
  _var = var_1
  if _var == nil then break end
  <block>
  end
end

目录
相关文章
|
7月前
|
存储 NoSQL Redis
Redis的Lua脚本有什么作用?
Redis Lua脚本用于减少网络开销、实现原子操作及扩展指令集。它能合并操作降低网络延迟,保证原子性,替代不支持回滚的事务。通过脚本,代码复用率提高,且可自定义指令,如实现分布式锁,增强Redis功能和灵活性。
265 1
|
9天前
|
监控 安全
公司用什么软件监控电脑:Lua 脚本在监控软件扩展功能的应用
在企业环境中,电脑监控软件对保障信息安全、提升效率至关重要。Lua 脚本在此类软件中用于扩展功能,如收集系统信息、监控软件使用时长及文件操作,向指定服务器发送数据,支持企业管理和运营。
28 6
|
6月前
|
消息中间件 NoSQL Java
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
246 0
|
2月前
|
缓存 分布式计算 NoSQL
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
37 2
|
3月前
|
存储 JSON Ubuntu
如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
|
7月前
|
缓存 NoSQL Java
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
281 0
|
4月前
|
存储 NoSQL Redis
Tair的发展问题之在Redis集群模式下,Lua脚本操作key面临什么问题,如何解决
Tair的发展问题之在Redis集群模式下,Lua脚本操作key面临什么问题,如何解决
|
6月前
|
JSON 监控 数据格式
使用Lua代码扩展上网行为管理软件的脚本功能
本文介绍了如何使用Lua脚本增强上网行为管理,包括过滤URL、记录用户访问日志、控制带宽和自动提交监控数据到网站。Lua是一种轻量级语言,适合编写扩展脚本。文中提供多个示例代码,如URL过滤器、用户活动日志记录器和带宽控制器,帮助用户根据需求定制网络管理功能。通过这些示例,用户可以快速掌握Lua在上网行为管理中的应用。
185 4
|
6月前
|
NoSQL API Redis
使用Redis Lua脚本实现高级限流策略
使用Redis Lua脚本实现高级限流策略
212 0
下一篇
DataWorks