首先看看一下闭合函数(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的更多相关文章

  1. lua迭代器和泛型for浅析

    (一) 首要概念要理清: 1. 在lua中,函数是一种"第一类值",他们具有特定的词法域."第一类值"表示在lua中函数与其他传统类型的值(例如数字和字符串)具 ...

  2. Lua迭代器和泛型for

    1.迭代器与closure 在lua中,迭代器通常为函数,每调用一次函数,会返回集合中的下一个元素.每个迭代器在成功调用的时候,都需要保存一些状态,closure(闭包)完美为迭代器运用而生. fun ...

  3. Step By Step(Lua迭代器和泛型for)

    Step By Step(Lua迭代器和泛型for) 1. 迭代器与Closure:    在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的"下一个"元素.每个迭代器都 ...

  4. lua闭合函数

    function count( ... ) return function( ... ) i = i+ return i end end local func = count(...) print(f ...

  5. Lua函数以及闭合函数的理解

    Lua函数以及闭合函数的理解 来源 http://blog.csdn.net/mydad353193052/article/details/48731467 词法域和第一类型 在C/C++,C#或者J ...

  6. Lua 迭代器

    第一种:lua迭代器的实现依赖于闭包(closure)特性 1.1 第一个简单的写法 --迭代器写法 function self_iter( t ) local i = 0 return functi ...

  7. Lua学习(4)——函数

    在Lua中函数的调用方式和C语言基本相同,如:print("Hello World")和a = add(x, y).唯一的差别是,如果函数只有一个参数,并且该参数的类型为字符串常量 ...

  8. Lua学习十一----------Lua迭代器

    © 版权声明:本文为博主原创文章,转载请注明出处 Lua迭代器 - 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址 - Lu ...

  9. Lua 学习之基础篇二<Lua 数据类型以及函数库 汇总>

    引言 前面讲了运算符,这里主要对Lua的数据处理相关的数据类型和函数库进行总结归纳,后面会再接着单独分开讲解具体使用. 首先因为Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储 ...

随机推荐

  1. 【笔记】JS数据类型总结

    JavaScript有六种数据类型,分别为undefined.null.number.string.Boolean.object,前面的五种是基础数据类型,也称之为原始类型,也就是无法再细分的基本类型 ...

  2. [DAViCHi/SeeYa/T-ARA][원더우먼][Wonder Woman]

    歌词来源:http://music.163.com/#/song?id=5371229 作曲 : 赵英秀 [作曲 : 赵英秀] [作曲 : 赵英秀] 作词 : K-Smith [作词 : KSmith ...

  3. Python之数据库模块安装 MySQLdb

    安装,下载地址 安装可能会报错, 1.需要安装VC++,到提示的地址中下载安装即可 2.在下载对应的包版本,如果是win7 64位2.7版本的python,就下载 MySQL_python-1.2.5 ...

  4. 基于easyui开发Web版Activiti流程定制器详解(六)——Draw2d详解(二)

    回顾: 上一篇我们介绍了Draw2d整体结构,展示了组件类关系图,其中比较重要的类有Node.Canvas.Command.Port.Connection等,这篇将进一步介绍Draw2d如何使用以及如 ...

  5. 什么是HOOK(钩子):消息拦截与处理

    对于Windows系统,它是建立在事件驱动机制上的,说白了就是整个系统都是通过消息传递实现的.hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并 ...

  6. Objective-C 与命名空间

    http://blog.csdn.net/michelle__/article/details/52528172 Objective-C 在Objective-C应用中的所有类名都必须是全局唯一的.命 ...

  7. C++ Primer Plus 第15章 友元、异常和其它

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/chudaxiakkk/article/details/30502807 第15章 友元.异常和其它 ...

  8. 【洛谷】【堆】P1168 中位数

    [题目描述:] 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数.即前1,3,5,……个数的中位数. ...

  9. 【转】Android随笔之——PackageManager详解

    参考:http://www.cnblogs.com/xingfuzzhd/p/3374504.html 今天要讲的是PackageManager.Android系统为我们提供了很多服务管理的类,包括A ...

  10. ElasticSearch 通过nginx做HTTP验证

    在ElasticSearch 的设置文件中如果设置了 network.host: 0.0.0.0 则表示ElasticSearch 服务是公开的任何ip都可以访问ElasticSearch 服务.这样 ...