从例子中学习闭包和范式for
来源:互联网 发布:ubuntu安装 中文语言包 编辑:程序博客网 时间:2024/05/22 11:32
又翻起了programming in lua这本书了,而且又看到 感谢贡献之人这段代码,今天就对这段代码做下分析。代码如下:
-- file: 'thanks.lua'-- desc: to print the list of the contributing guysfunction list_iter (t) local i = 0 local n = table.getn(t) return function () i = i + 1 if i <= n then return t[i] end endendhelpful_guys = { "----参与翻译----", "buxiu", "凤舞影天", "zhang3", "morler", "lambda", "sunlight", "\n", "----参与校对----", "凤舞影天", "doyle", "flicker", "花生魔人", "zhang3", "Kasi", "\n"}for e in list_iter( helpful_guys ) do print(e)end
对于这段代码,我们分两个部分来讲,第一部分是闭包,第二部分是范式for的运行过程.
首先先讲闭包,简单一点说,闭包就是 一个内部函数,它可以访问一个或多个外部函数的外部局部变量
结构:包含两个函数,一个是闭包自己,一个是工厂(创建闭包的函数)
-- 这里list_iter函数是创建闭包的工厂function list_iter( t ) local i = 0 local n = table.getn( t ) -- 匿名函数,list_iter函数的返回值 return function () -- 变量i、n和t相对于这个匿名函数,是个外部函数(list_iter)的局部变量 i = i + 1 if i <= n then return t[i] end endend
先看下上面的list_iter函数,它的返回值是一个函数,这个函数保存着三个外部的局部变量i,n和t
大家想一下:
fFunc = list_iter( {"a", "b"} )
运行list_iter的返回值就是一个函数, 它保存了三个值,i=0, n=2, t={“a”, “b”}
第一次运行fFunc函数, 即
print( fFunc() )
输出结果为 a
因为 fFunc 它是一个函数,运行的时候
i=i+1 这时i=0+1=1
t[1] 就是 a
运行完之后,这个fFunc的保存的 外部的局部变量 i变成了1
同理再运行一下 fFunc时,
输出的结果为 b
同时,这个fFunc的保存的 外部的局部变量 i变成了2
这时候再运行一下的时候,结果就是nil, 因为
i=2+1 等于 3
i<=n不成立了(3<=2不成立)
所以接下来运行的时候,结果都是为nil,
但是每运行一次的时候,fFunc这个闭包的局部变量 i就会加1
function iter_list( t ) local i = 0 local n = table.getn(t) return function() i = i + 1 print( "i=", i ) if i<= n then return t[i] end endendfFunc = iter_list( {"a", "b"} )print( fFunc() )print( fFunc() )print( fFunc() )print( fFunc() )
运行结果:
接下来讲一下范式for的运行过程
其语法如下
for <var-list> in <exp-list> do <body>end
其中
var-list 是一个或多个以逗号分割的变量名列表
exp-list 是一个或多个以逗号分割的表达式列表,迭代函数(闭包),状态常量和控制变量
通常情况下 exp-list 为:迭代工厂的调用。 即: iter_list() 其返回值是一个闭包
其运行过程为:
do -- _f为迭代函数,_s为状态常量,_var为控制变量 local _f, _s, _var = explist while true do -- 迭代函数的参数有两个 -- 第一个是状态常量_s, 这个值是explist返回的第二个参数 -- 第二个是控制常量,第一次的值是explist返回的第三个参数,后面的值是上次运行_f返回的第一个返回值 local var_1, ... , var_n = _f( _s, _var ) -- 接下来_f的第二个参数,变成上一次运行_f返回的第一个值 _var = var_1 -- 如果控制变量为nil就结束 if _var == nil then break end block endend
上面的解释可能一开始看不懂,没关系,接下来根据实例来说明一下,这里用最开始那个感谢的函数来说明:
function list_iter(t) local i = 0 local n = table.getn(t) return function () i = i + 1 if i <= n then return t[i] end endendhelpful_guys = { "----参与翻译----", "buxiu", "凤舞影天", "zhang3", "morler", "lambda", "sunlight", "\n", "----参与校对----", "凤舞影天", "doyle", "flicker", "花生魔人", "zhang3", "Kasi", "\n"}-- 这里 in 后面的结果,我们希望是一个迭代函数,一个状态常量,一个控制常量-- 但是这里是 list_iter( helpful_guys )-- 也就是说 local _f, _s, _var = list_iter( helpful_guys )的返回值-- 因为list_iter只有一个返回值,所以这里的三个变量分别为-- _f 为闭包, _s = nil, _var = nilfor e in list_iter( helpful_guys ) do -- 第一次运行_f的时候,返回值是helpful_guys的第一个元素;"----参与翻译----" -- 根据上面分析for的运行过程,可知,这里就是一直运行_f函数,直到其返回值为nil就就结束 print(e)end
上面的
for e in list_iter( helpful_guys ) do print( e )end
等价于
_f, _s, _var = list_iter( helpful_guys )for e in _f, _s, _var do print( e )end
运行的_f的过程中,其实是有传入状态常量_s,和后续变化的控制变量_var,只是这里闭包函数没有参数而已
我们可以修改一下迭代工厂,就可以看到状态常量_s和控制变量_var
function list_iter( t ) local i = 0 local n = table.getn( t ) -- _s为状态常量,其值是迭代工厂返回的第二个值,这里就是 "我是状态常量" -- _var为控制变量,第一次是迭代工厂返回的第三个值,后续是闭包运行返回的第一个值 return function ( _s, _var ) print( "状态常量:", _s ) print( "控制量:", _var ) i = i + 1 if i <= n then return t[i] end end, "我是状态常量", "我是初始的控制变量"endfor e in list_iter( {"a"} ) do print(e)end
运行结果:
上面就是从例子中学到的闭包和范式for的运行过程,有什么问题,欢迎留言讨论
- 从例子中学习闭包和范式for
- 闭包的学习例子
- android SQLite从例子中学习
- 从一个例子看Python3.x中序列解包
- 数据库中范式和反范式
- js 闭包范式概述
- JavaScript学习-闭包的经典例子
- 从一个小例子再次理解闭包
- 从例子中学习 go 语言 —— 基本语法
- 从一个简单的例子学习For循环(适合刚刚学习C语言的同学)
- 学习java for循环和枚举类型的小小例子
- 从一个例子学习 instanceof 和 getclass 的区别
- (function (){})(); JS 闭包 (Closure) 范式
- 简单谈谈关系数据库中范式理论(含例子)
- js闭包和for循环
- cloudsim network包例子学习
- 范式和反范式
- 如何从Eclipse工程中导入和导出jar包
- 图解快速排序
- RecyclerView实现广告轮播图
- ffmpeg
- 开博了
- Introduction to 3D Game Programming with DirectX 11学习笔记 5 渲染管线(一)
- 从例子中学习闭包和范式for
- fdghhhhhhhhhhhh
- 卷积
- [iBET Malaysia]Sports Book Rebate 0.35% Bonus
- 消息摘要加密算法MD
- CentOS(Linux) 下vi编辑器用法大全
- iOS学习笔记之-使用UITouch来根据手指位置移动图片
- 完美学术ppt
- Nginx安装