[Lua] 迭代器 闭合函数 与 泛型for
首先看看一下闭合函数(closure),见如下代码:
- function newCounter()
- local i = 0 -- 非局部变量(non-local variable)
- return function () -- 闭合函数(closure)
- i = i +
- return i
- end
- end
- c1 = newCounter()
- print(c1()) --
- print(c1()) --
- c2 = newCounter()
- print(c2()) --
- print(c1()) --
- print(c2()) --
闭合函数可以用来实现迭代器(iterator)(迭代器用来遍历集合,每调用一次函数,即返回集合中的下一个元素)。
例如:遍历一个table的时候,我们经常使用如下方式。
- t = {'x', 'y', 'z'}
- for k, v in ipairs(t) do
- print(k .. " " .. v)
- end
- -- 打印结果
- -- 1 x
- -- 2 y
- -- 3 z
我们可以用while遍历集合,也可以用for,并且用for会容易很多,下面看一下for的语义:
- -- A for statement like
- for var_1, ···, var_n in explist do block end
- -- is equivalent to the code:
- do
- local f, s, var = explist
- while true do
- local var_1, ···, var_n = f(s, var)
- var = var_1
- if var == nil then break end
- block
- end
- end
- -- Note the following:
- -- explist is evaluated only once. Its results are an iterator function, a state, and an initial value for the first iterator variable.
- -- f, s, and var are invisible variables. The names are here for explanatory purposes only.
- -- You can use break to exit a for loop.
- -- The loop variables var_i are local to the loop; you cannot use their values after the for ends. If you need these values, then assign them to other variables before breaking or exiting the loop.
注:
1 for做的第一件事就是对in后面的表达式求值,这些表达式应该返回3个值供for保存:迭代器函数(f)、恒定状态(s)、控制变量的初值(var),不足的值用nil补足。
2 在初始化之后,for会以恒定状态s和控制变量var来调用迭代函数f,然后for将迭代起的返回值赋予变量列表中的变量(var_1, var_2 ..., var_n),其中var_1称为控制变量,当返回的var_1为nil时,循环终止。
下面是书中的Lua实现ipair的例子:
- t3 = {"x", "y", "z"}
- local function iter (a, i)
- i = i +
- local v = a[i]
- if v then
- return i, v -- 第一个返回值是控制变量
- end
- end
- function __ipairs (a)
- return iter, a, 0 -- 3个值,迭代器、恒定状态、控制变量。 第一次是iter(a, 0),之后则是iter(a, i)
- end
- for i, v in __ipairs(t3) do
- print(i .. " " .. v)
- end
- -- 输出结果:
- -- 1 x
- -- 2 y
- -- 3 z
结合上面for的语义表达式,来分析上面这段代码,__ipairs是一个工厂,生产迭代器iter,迭代器的初始参数是a和0,即恒定状态(a)和控制变量(i),iter的返回值是控制变量i和返回值a[i]。
pairs与ipairs类似,但key是无序的,它的迭代器函数是 Lua中的一个基本函数next,在调用next(t, k)时,k是table t的一个key,此调用会以table中的任意次序返回一组值,而调用next(t, nil)时,返回table的第一组值。若没有下一组值的时候,next返回nil。
- function pairs(t)
- return next, t, nil
- end
也可以直接使用next:
- for k, v in next, t do
- <loop body>
- end
[Lua] 迭代器 闭合函数 与 泛型for的更多相关文章
- lua迭代器和泛型for浅析
(一) 首要概念要理清: 1. 在lua中,函数是一种"第一类值",他们具有特定的词法域."第一类值"表示在lua中函数与其他传统类型的值(例如数字和字符串)具 ...
- Lua迭代器和泛型for
1.迭代器与closure 在lua中,迭代器通常为函数,每调用一次函数,会返回集合中的下一个元素.每个迭代器在成功调用的时候,都需要保存一些状态,closure(闭包)完美为迭代器运用而生. fun ...
- Step By Step(Lua迭代器和泛型for)
Step By Step(Lua迭代器和泛型for) 1. 迭代器与Closure: 在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的"下一个"元素.每个迭代器都 ...
- lua闭合函数
function count( ... ) return function( ... ) i = i+ return i end end local func = count(...) print(f ...
- Lua函数以及闭合函数的理解
Lua函数以及闭合函数的理解 来源 http://blog.csdn.net/mydad353193052/article/details/48731467 词法域和第一类型 在C/C++,C#或者J ...
- Lua 迭代器
第一种:lua迭代器的实现依赖于闭包(closure)特性 1.1 第一个简单的写法 --迭代器写法 function self_iter( t ) local i = 0 return functi ...
- Lua学习(4)——函数
在Lua中函数的调用方式和C语言基本相同,如:print("Hello World")和a = add(x, y).唯一的差别是,如果函数只有一个参数,并且该参数的类型为字符串常量 ...
- Lua学习十一----------Lua迭代器
© 版权声明:本文为博主原创文章,转载请注明出处 Lua迭代器 - 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址 - Lu ...
- Lua 学习之基础篇二<Lua 数据类型以及函数库 汇总>
引言 前面讲了运算符,这里主要对Lua的数据处理相关的数据类型和函数库进行总结归纳,后面会再接着单独分开讲解具体使用. 首先因为Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储 ...
随机推荐
- mkdirp——递归创建目录及其子目录
如果要创建目录A并创建目录A的子目录B,没有用-p参数的情况下mkdir会逐个创建目录(mkdir A; mkdir A/B); 加上参数-p就可以直接创建2个目录mkdir -p A/B( 如果目录 ...
- Java8新特性 -- Lambda 方法引用和构造器引用
一. 方法引用: 若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用” 要求 方法的参数和返回值类型 和 函数式接口中的参数类型和返回值类型保持一致. 主要有三种语法格式: 对象 :: ...
- 在Ubuntu Desktop中安装软件
1. 安装好虚拟机后,可以先打开firefox,看是否可以访问外部的网页. 2. 如果在公司内网,可能访问不起,需要添加代理,确保可以访问外部的网页. 3. 更新软件源 sudo apt update ...
- Laravel中如何将单个routes.php分割成多个子文件
随着业务逻辑越来越复杂,routes.php文件也会变得越来越庞大,为了便于管理,我们可以像管理配置文件那样将其分割成多个子文件,这实现起来很简单: // app/routes.php ... // ...
- Ubuntu16.04如何彻底删除Apache2
虽然作为运维人员通常情况不建议随意删除Linux系统上面的任何软件,主要指生产环境下,测试环境也不能太随意. 但是有的时候,比如系统环境要变一变,我们就需要替换一些淘汰的软件,对此我们一般都会删除. ...
- datagrid 完整dom结构
<!-- datagrid的最外层容器,可以使用$(target).datagrid('getPanel')或者$.data(target,'datagrid').panel得到这个DOM对象, ...
- jenkins slave 挂载
http://blog.sina.com.cn/s/blog_13cc013b50102wiau.html
- P1481 魔族密码
题目描述 风之子刚走进他的考场,就…… 花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花) 风之子:我呕……(杀死人的眼神)快说题目!否则……-_-### 花花:……咦好冷我们现在 ...
- 浅谈IC行业产业链以及贸易商在产业链中的作用 2008-10-16 12:45[转自Michael的博客]
随着集成电路行业在中国的迅猛发展, 中国的低成本劳动力和开放的引入外资政策, 使得全球电子产品生产厂商为了降低成本, 增加产品市场竞争力, 纷纷在中国设立生产线, 而中国不断膨胀的购买力也促进了这一产 ...
- jquery 中的dom操作
jquery DOM 分为元素操作.属性操作.样式操作. 一.元素操作 1.查找 ①工具:jQuery选择器 2.创建和添加 ①代码格式:变量 = $('要创建的元素'): 注意点: 1 要使用标准的 ...