首先看看一下闭合函数(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. Hadoop HA on Yarn——集群启动

    这里分两部分,第一部分是NameNode HA,第二部分是ResourceManager HA (ResourceManager HA是hadoop-2.4.1之后加上的) NameNode HA 1 ...

  2. Matlab面向对象编程基础

    DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...

  3. Mysql数据库的mysql Schema 究竟有哪些东西& 手工注入的基础要领

    #查看数据库版本号 mysql> select @@version; +------------+ | @@version  | +------------+ | 5.5.16-log | +- ...

  4. 有关linqtosql和EF的区别

    LINQ to SQL和Entity Framework都是一种包含LINQ功能的对象关系映射技术.他们之间的本质区别在于EF对数据库架构和我们查询的类型实行了更好的解耦.使用EF,我们查询的对象不再 ...

  5. ES6新特性4:字符串的扩展

    本文摘自ECMAScript6入门,转载请注明出处. 一.ES5字符串函数 concat: 将两个或多个字符的文本组合起来,返回一个新的字符串. indexOf: 返回字符串中一个子串第一处出现的索引 ...

  6. dbcp最终版本

    注意:我们在使用有参的queryrunner的时候,不需要关闭connection和DataSource 这些都queryrunner 都替我们完成.我们不需要关系资源释放. 工具类: package ...

  7. gulp插件(8) - gulp-sourcemaps(生成sourcemap)

    功能描述生成sourcemap文件(什么是sourcemap?请参考,简单讲就是文件压缩后不利于查看与调试,但是有了sourcemap,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码) 插 ...

  8. 视频直播时的QoS策略

    一.如何判断当前的网络状况 可以以发送一帧视频数据的时间为依据,判断当前网络拥塞情况.    网络中出现丢包和抖动,导致接收端接收数据超时,会激发发送端数据重传,重传机制本身挤占网络带宽,导致send ...

  9. YUV420图像旋转90算法的优化

    在做android摄像头捕获时,发现从android摄像头出来的原始视是逆时针旋转了90度的,所以须要把它顺时针旋转90.android视频支持的是NV21格式,它是一种YUV420的格式.当然,始果 ...

  10. 博弈论之SG函数

    Fibonacci again and again(http://acm.hdu.edu.cn/showproblem.php?pid=1848) Time Limit: 1000/1000 MS ( ...