【什么是闭包?】

闭包在Lua中是一个非常重要的概念,闭包是由函数和与其相关的引用环境组合而成的实体。我们再来看一段代码:

function newCounter()
local i =
return function () -- 匿名函数
i = i +
return i
end
end c1 = newCounter()
print(c1())
print(c1())

根据刚刚说的闭包的概念,结合上面的代码,来说说这个概念。闭包=函数+引用环境。上述代码中的newCounter函数返回了一个函数,而这个返回的匿名函数就是闭包的组成部分中的函数;引用环境就是变量i所在的环境。实际上,闭包只是在形式和表现上像函数,但实际上不是函数,我们都知道,函数就是一些可执行语句的组合体,这些代码语句在函数被定义后就确定了,并不会再执行时发生变化,所以函数只有一个实例。而闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例,就好比相同的类代码,可以创建不同的类实例一样。在看别人的文章时,看到有这样的说法:子函数可以使用父函数中的局部变量,这种行为就叫做闭包!这种说法其实就说明了闭包的一种表象,让我们从外在形式上,能更好的理解什么是闭包。至于深层次的闭包,我们接着继续。

【再看闭包】

看过我博客的朋友都清楚,我之前的博客都是写的关于C++的东西,对于学习C++的我,理解Lua的闭包时,确实存在一些“难度”。首先,在Lua中,创建一个函数,就像定义一个普通类型值一样的,也就是我之前的博文中说的,Lua中的函数和和普通类型是没有区别的。Lua中的函数就是所谓的“第一类值”,它可以被存放在变量或数据结构中,可以当做参数传递给另一个函数,可以是一个函数的返回值,还可以在运行期间被创建。Lua中的函数就是这样的一种“东西”,它很灵活。还记得我在《Lua中的函数》博文中提到的“非局部的变量”这个概念么?这是一个非常很重要的概念,它可以理解为不是在局部作用范围内定义的一个变量,同时,它又不是一个全局变量,也就是大家说的upvalue,由于有了这样的一种变量的存在,就成全了Lua中的闭包。这种变量主要应用在嵌套函数和匿名函数里。我们都知道,可以在Lua的函数中再定义函数,也就是内嵌函数,内嵌函数可以访问外部函数已经创建的所有局部变量,而这些变量就被称为该内嵌函数的upvalue,upvalue实际指的是变量而不是值,这些变量可以在内部函数之间共享,比如以下代码:

function Fun1()
local iVal = -- upvalue
function InnerFunc1() -- 内嵌函数
print(iVal) --
end function InnerFunc2() -- 内嵌函数
iVal = iVal +
end return InnerFunc1, InnerFunc2
end -- 将函数赋值给变量,此时变量a绑定了函数InnerFunc1, b绑定了函数InnerFunc2
local a, b = Fun1() -- 调用a
a() -->10 -- 调用b
b() -->在b函数中修改了upvalue iVal -- 调用a打印修改后的upvalue
a() -->20

上述这段简单的代码,就验证了在内嵌函数中是共享upvalue的,就好比C++类中的成员函数可以访问和修改成员变量一样。

【使用闭包】

可以看到闭包是数据和行为的结合体,就好比C++中的类,这样就使得闭包具有较好的抽象能力,在某些场合下,我们需要记住某次调用完成以后数据的状态,就好比C++中的static类型的变量,每次调用完成以后,static类型的变量并不会被清除。使用闭包就可以很好的完成该功能,在下一篇博文中,我将会讲到使用闭包完成迭代器功能。

Lua中的闭包的更多相关文章

  1. [译] Closures in Lua - Lua中的闭包

    原文:(PDF) . 摘要 一等(first-class)函数是一种非常强大的语言结构,并且是函数式语言的基础特性.少数过程式语言由于其基于栈的实现,也支持一等函数.本文讨论了Lua 5.x用于实现一 ...

  2. [转][译] Closures in Lua - Lua中的闭包

    http://www.cnblogs.com/plodsoft/p/5900270.html?utm_source=tuicool&utm_medium=referral 原文:(PDF) . ...

  3. 两个函数彻底理解Lua中的闭包

    本文通过两个函数彻底搞懂Lua中的闭包,相信看完这两个函数,应该能理解什么是Lua闭包.废话不多说,上 code: --[[************************************** ...

  4. lua中的闭包概念的学习笔记

    1.闭包的由来: 个人理解,lua中之所以出现闭包的概念,完全是因为lua中允许函数的嵌套定义,并且在内嵌函数中使用了外包函数中定义的局部变量,例如c.c#就不允许函数的嵌套定义(但是允许函数的嵌套调 ...

  5. lua中的闭包小结

    function newCounter() return function() i=i+ return i end end c1=newCounter() print(c1()) print(c1() ...

  6. 【Unity游戏开发】浅谈Lua和C#中的闭包

    一.前言 目前在Unity游戏开发中,比较流行的两种语言就是Lua和C#.通常的做法是:C#做些核心的功能和接口供Lua调用,Lua主要做些UI模块和一些业务逻辑.这样既能在保持一定的游戏运行效率的同 ...

  7. Lua中的函数

    [前言] Lua中的函数和C++中的函数的含义是一致的,Lua中的函数格式如下: function MyFunc(param) -- Do something end 在调用函数时,也需要将对应的参数 ...

  8. Lua中闭包详解 来自RingOfTheC[ring.of.the.c@gmail.com]

    这些东西是平时遇到的, 觉得有一定的价值, 所以记录下来, 以后遇到类似的问题可以查阅, 同时分享出来也能方便需要的人, 转载请注明来自RingOfTheC[ring.of.the.c@gmail.c ...

  9. Cocos2d-x 脚本语言Lua中的面向对象

    Cocos2d-x 脚本语言Lua中的面向对象 面向对象不是针对某一门语言,而是一种思想.在面向过程的语言也能够使用面向对象的思想来进行编程. 在Lua中,并没有面向对象的概念存在,没有类的定义和子类 ...

随机推荐

  1. 洛谷 P1101 单词方阵

    题目链接 https://www.luogu.org/problemnew/show/P1101 题目描述 给一n×n的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中 ...

  2. 即将发布的 ASP.NET Core 2.2 会有哪些新玩意儿?

    今年 6 月份的时候时候 .NET 团队就在 GitHub 公布了 ASP.NET Core 2.2 版本的 Roadmap(文末有链接),而前两天 ASP.NET Core 2.2 预览版 2 已经 ...

  3. java常识

    什么是java语言? java语言是美国Sun公司,在1995年推出的高级编程语言.所谓编程语言,是计算机的语言,人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能. java语言发展历 ...

  4. JS 函数节流与防抖

    前言 事件的触发权很多时候属于用户,可能会出现下列问题: 向后台发送数据,用户频繁触发,对服务器造成压力: 一些浏览器事件,如window.onresize,window.mousemove等,触发的 ...

  5. svnsync同步svn

    使用svnsync实现已有版本库的镜像svn不支持分布式开发,所以把svn版本库保存在一台服务器上是不安全的.制作一个镜像svn版本库有多种方式,我采用subversion自带的svnsync程序. ...

  6. thymeleaf循环

    th:each属性用于迭代循环,语法:th:each="obj,iterStat:${objList}"迭代对象可以是Java.util.List,java.util.Map,数组 ...

  7. 【apache】No input file specified

    默认的 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]规则在apache fastcgi模式下会导致No input file specified. 修改成 Re ...

  8. Linux 学习 (四) 帮助命令

    Linux达人养成计划 I 学习笔记 man 命令 获取指定命令的帮助 man的级别 1:查看命令的帮助 2:查看可被内核调用的函数的帮助 3:查看函数和函数库的帮助 4:查看特殊文件的帮助(主要是/ ...

  9. servlet篇 之 跳转问题

    servlet中的跳转: 跳转本质上是对文件传输操作 进行 封装. 例如:客户端访问一个servlet,在servlet中需要把已经写好的页面hello.html返回给客户端浏览器,需要用io来实现这 ...

  10. [模板] CDQ分治&&BZOJ3262:陌上花开

    简介 CDQ分治是分治的一种, 可以看做归并排序的扩展, 利用离线将一些 \(O(n)\) 的暴力优化到 \(O(log n)\). 它可以用来顶替一些高级(log)数据结构等. 一般地, CDQ分治 ...