`
avenje
  • 浏览: 13474 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

(5)LUA程序设计-迭代器(state iterator & stateless iterator)

 
阅读更多

1.迭代器与closure的关系

所谓迭代器,就是对一个集合的遍历,比如遍历一个table数组,我们必须在每遍历完一个元素之后,我们必须记住下一个元素的索引。

前几节我们学过了闭合函数,它存在的非局部的变量,就是能够在多次调用闭合函数(返回的函数+非局部的变量)后,保留非局部变量的值,利用这一点,我们可以很容易的自定义一个迭代器

比如遍历一个t = {12,23,15,19}数组,自定义迭代器如下

function values(t)

local i = 0;

return function() i = i+1 return t[i] end;

end

遍历方式有两种while xxx do ... end 或者用本节讲的for来遍历,

t = {12,23,15,19};

前者方面

iter = values(t);

while true do

local elem = iter();

if nil == elem then break end;

print(elem);

end

后者方法,采用for

for elem in values(t) do

print(elem);

end

两种方法,显然for比较简洁一些,for会多次调用<expr-list>(泛型for格式:for <val-list> in <expr-list> do ... end)所处的迭代器(称为迭代工厂也行)

下面举一个更为复杂的迭代器,遍历 输入文件当中的单词,必须用两个变量来记住当前读到的文字所处行line,以及当前的列的位置pos

首先创建一个迭代器

function allwords()

local line = io.read(); --读取一行文本

local pos = 1;--初始当前为第一列的位置

return function()

while line do -- 至少有一行文本

local s,e = stirng.find(line,"%w+",pos) --调用string.find方法,第一个参数为当前文本串,第二个参数为正则表达式,表示单词,第三个参数表示,从line的第pos列开始查找

if s then -- 找到了单词的情况

pos = e+1; -- 移动pos的索引位置

return string.sub(line,s,e); --节取line从s到e索引对应的单词,并返回

else

line = io.read() --如果上一行文本内已经找不到单词了,再读取一行

pos = 1--重新将pos置到第一列

end

end

return nil --没有文本,返回空

end

end

我们用for可以简化代码,实现遍历如下:

for word in allwords() do

print(word)

end

 

 

梦之幻时尚睡衣纺 http://shop.paipai.com/442560143

2 强大的泛型for

我们应该正确理解LUA提供的FOR泛型的强大之处,

我们知道,泛型for格式:for <val-list> in <expr-list> do ... end,正常情况下<val-list>这个变量列表可以是一个或多个,一般是三个,而<expr-list>也可以是一个或多个表达式,但一般情况是一个.

上面所举的两个例子(遍历数组,遍历文件当中的单词,我们称之无状态的迭代器 ,为什么?)有时候,我们不想迭代器本身保留着一些状态,或者控制变量,而希望迭代器本身不存在什么状态,而是将诸如控制变量,恒定状态等信息从迭代器中分离出来,这时候,我们就需要泛型for了

泛型for支持每次调用迭代工厂后,返回迭代器的一些状态给<val-list>,即for ... in ... do ... end在处理时,首先处理in后面的表达式,一般处理后返回三个值,分别是:迭代函数(工厂)func,恒定状态 list,控制变量 index 这三个值,之后,利用返回的后两个值(list,index作为func函数的参数,调用func,返回给in之前的变量列表<var-list>)

举例:(无状态迭代器,状态交给了泛型for)还是以遍历数组为例(下面的代码其实是LUA ipairs方法的实现原理)

 

t = {12,23,15,19}

function values(t,i)

i = i+1;

return function() return i , t[i] end;

end

function iter(t)

return values,t,0

end

定义了上面的iter迭代器之后,我们可以这样子遍历数组了

for i,v in iter(t) do

print(i,v);

end

3较为复杂的有状态迭代器

我们将本节1当中举的例子(代码如下)有状态迭代器,修改成较复杂的有状态迭器

 

修改前:

function allwords()

local line = io.read(); --读取一行文本

local pos = 1;--初始当前为第一列的位置

return function()

while line do -- 至少有一行文本

local s,e = stirng.find(line,"%w+",pos) --调用string.find方法,第一个参数为当前文本串,第二个参数为正则表达式,表示单词,第三个参数表示,从line的第pos列开始查找

if s then -- 找到了单词的情况

pos = e+1; -- 移动pos的索引位置

return string.sub(line,s,e); --节取line从s到e索引对应的单词,并返回

else

line = io.read() --如果上一行文本内已经找不到单词了,再读取一行

pos = 1--重新将pos置到第一列

end

end

return nil --没有文本,返回空

end

end

修改后:

function allwords()

local state = {line = io.read(),pos = 1} --将(读取一行文本--初始当前为第一列的位置)的数据放到一个table里边,名为state

return myIterator,state

end

function myIterator(state)

while state.line do -- 至少有一行文本

local s,e = stirng.find(state.line,"%w+",state.pos) --调用string.find方法,第一个参数为当前文本串,第二个参数为正则表达式,表示单词,第三个参数表示,从line的第pos列开始查找

if s then -- 找到了单词的情况

state.pos = e+1; -- 移动pos的索引位置

return string.sub(state.line,s,e); --节取line从s到e索引对应的单词,并返回

else

state.line = io.read() --如果上一行文本内已经找不到单词了,再读取一行

state.pos = 1--重新将pos置到第一列

end

end

return nil --没有文本,返回空

end

修改后的遍历跟修改前一样

 

 

梦之幻时尚睡衣纺 http://shop.paipai.com/442560143

for word in allwords() do

print(word)

end

-------------------迭代器就讲到这里,下一节将讲解-(6)LUA程序设计-编译执行与错误(compile 、run & error)处理------------

 

LUA技术交流群,请加Q群:139315537,加入请注明来源。

分享到:
评论

相关推荐

    lua-nginx-module-0.10.13

    Lua-Nginx-Module,简称lua-nginx-module,是Nginx服务器的一个重要扩展模块,它将强大的Lua脚本语言集成到Nginx中,允许用户在Nginx配置文件中直接编写Lua代码,极大地增强了Nginx的功能性和灵活性。版本0.10.13是...

    lua-nginx-module-0.10.9rc7

    《Lua在Nginx中的应用:Lua-Nginx-Module 0.10.9rc7详解》 Lua-Nginx-Module是Nginx服务器中一个强大的扩展模块,允许我们在Nginx配置文件中直接嵌入Lua脚本,极大地提高了Nginx处理动态请求的能力。本文将详细探讨...

    lua-nginx-module-master.zip

    2. **配置使用**:在Nginx的配置文件(如`nginx.conf`)中,你可以通过`lua_code_cache`指令控制Lua脚本的缓存策略,`init_by_lua_file`或`init_by_lua`用于执行启动时的Lua代码,`set_by_lua_block`、`rewrite_by_...

    所有版本LUA源码

    所有版本LUA源码 lua-5.3.5 lua-5.3.4 lua-5.3.3 lua-5.3.2 lua-5.3.1 lua-5.3.0 lua-5.2.4 lua-5.2.3 lua-5.2.2 lua-5.2.1 lua-5.2.0 lua-5.1.5 lua-5.1.4 lua-5.1.3 lua-5.1.2 lua-5.1.1 lua-5.1 lua-5.0.3 lua-...

    lua-resty-core, 新的基于 lua Nginx 模块的API.zip

    lua-resty-core, 新的基于 lua Nginx 模块的API 电子邮件名称lua-resty-core - 用于ngx_http_lua_module和/或者ngx_stream_lua_module的基于new的Lua table-内容名称状态概要说明描述先决条件API实现了r

    lua-devel-5.3.4-12.el8.aarch64

    安装 `lua-devel` 包后,开发者可以编写 C/C++ 代码来创建 Lua 模块,通过 `luaL_newstate` 创建 Lua 状态机,`luaL_openlibs` 打开标准库,然后使用 `luaL_loadbuffer` 或 `luaL_dofile` 加载和运行 Lua 脚本。...

    lua-resty-limit-traffic, 在 openresty/ngx_lua中,用于限制和控制流量的Lua库.zip

    lua-resty-limit-traffic, 在 openresty/ngx_lua中,用于限制和控制流量的Lua库 电子邮件名称lua-resty-limit-traffic - 用于限制和控制 openresty/ngx_lua中流量的Lua库目录名称状态概要说明描述安装工具社区服务...

    lua-cjson-2.1.0

    5. **自定义配置**:用户可以通过配置选项来定制`lua-cjson`的行为,例如设置日期格式、控制浮点数精度等。 **三、在Nginx中的应用** `lua-cjson`与Nginx结合,可以实现强大的服务器端脚本功能。Nginx的HTTP Lua...

    lua-resty-mongol-master已编译

    lua-resty-mongol是基于OpenResty的一个lua库,专为处理MongoDB连接和操作而设计。标题"lua-resty-mongol-master已编译"表明我们已经获取到lua-resty-mongol的最新稳定版本,并且完成了编译过程,准备在不同的操作...

    EmmyLua-AttachDebugger-1.0.0.4.zip

    EmmyLua是一款专门为Lua语言开发的强大的调试工具,它允许开发者在IntelliJ IDEA这样的集成开发环境中进行断点调试,极大地提高了Lua编程的效率和精确性。"EmmyLua-AttachDebugger-1.0.0.4.zip"是这个工具的一个特定...

    lua-devel-5.1.4-4.1.el6.x86_64.rpm

    安装nginx_lua模块时候需要先安装nginx的依赖包,安装命令rpm -ivh lua-devel-5.1.4-4.1.el6.x86_64.rpm

    lua-nginx-module.zip

    5. 缓存机制:lua-nginx-module支持基于内存的缓存,可以提高高并发场景下的响应速度。 四、lua-nginx-module的使用 在使用lua-nginx-module时,我们需要在Nginx配置文件中引入该模块,并定义Lua脚本。例如,以下...

    emmylua-pr-0.3.103.vsix

    4. **调试支持**:集成Lua调试器,允许设置断点、查看变量值,方便调试程序。 5. **格式化工具**:自动格式化代码,保持代码风格统一,提高代码可读性。 6. **Linter**:检查代码风格和潜在问题,遵循一定的编码...

    云风-lua源码欣赏-lua-5.21

    通过了解源文件划分,读者可以更好地理解Lua的模块化设计,而代码风格部分则有助于我们了解Lua编程的一致性和规范性。 接下来,书中讨论了Lua的虚拟机(VM)实现,包括字节码的翻译和预编译过程。这部分内容对于...

    lua-resty-mongol_openresty连接mongoldb的lua库

    “lua-resty-mongol”是专为OpenResty设计的一个lua库,用于在OpenResty环境中与MongoDB数据库进行交互。这个库的创建是为了在高性能的Web服务中无缝集成MongoDB的数据操作功能,它允许开发者使用lua脚本直接处理...

    lua-nginx-module-0.10.20.tar.gz

    《Lua在Nginx中的应用:lua-nginx-module-0.10.20详解》 Lua语言以其轻量级、高效和强大的脚本能力,近年来在Web开发领域备受青睐,尤其是在Nginx服务器中,Lua与Nginx的结合使用,通过lua-nginx-module模块,实现...

    lua-resty-validation, 用于Lua和OpenResty的验证库( 输入验证和筛选).zip

    lua-resty-validation, 用于Lua和OpenResty的验证库( 输入验证和筛选) lua-resty-validationlua-resty-validation 是用于Lua和OpenResty的可以扩展链接验证和过滤库。带lua-resty-validation的 Hello Worldlocal val

    lua-cjson-2.1.0-已编译

    Lua-cjson是一个为Lua语言设计的JSON(JavaScript Object Notation)编码和解码库,它在Lua环境中提供了高效且易用的JSON接口。JSON是一种轻量级的数据交换格式,广泛应用于网络服务之间的数据通信以及存储数据。Lua...

    Lua程序设计&5.1中文手册&5.1源码

    标题中的“Lua程序设计”指的是使用Lua语言进行程序开发的方法和技巧,而“5.1中文手册”则是针对Lua 5.1版本的官方文档的中文翻译版,提供了详尽的语法说明和使用指南。“5.1源码”则意味着包含了Lua 5.1版本的原始...

    nginx、lua、jwt安装包及蓝绿发布代码

    nginx安装lua、jwt模块,通过lua验证jwt实现蓝绿发布样例demo,配置直接可用 luajit2-2.1-20220411.tar.gz #luajit官网存在一定的坑,下载openresty的优化版本 lua-nginx-module-0.10.22.tar.gz # 0.10.16 以后都...

Global site tag (gtag.js) - Google Analytics