1、闭包的由来:

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

以下是函数嵌套定义的一个例子:

 function fun1(n)
local function fun2()
print(n)
end return fun2
end

fun1叫做fun2的外包函数,fun2叫做fun1的内嵌函数,并且这中内嵌与外包关系是允许传递的。什么意思呢?就是fun1的外包函数也是fun2的外包函数,fun2的内嵌函数也是fun1的内嵌函数。

我们都知道,函数中定义的局部变量的生命周期就是在函数运行完后就结束了。假如现在有如下逻辑:

 fun3 = fun1()
fun3()

执行结果如下:

从执行结果上看,2048的生命周期好像不是在fun1执行完就结束的,看着像是在fun2执行完才结束的。事实是这样的吗?

当fun3被调用时,其函数体访问了外部的局部变量n。当调用fun2函数时,创建fun2的fun1函数已经返回了,即执行结束,那么外部局部变量的生命周期也就结束了,这个时候在fun2中继续如何访问局部变量 n 呢?

闭包就是为了解决这个问题出现的。

其实不同的语言,对该问题有不同的处理方式,例如c、c#直接就不允许函数的嵌套定义,从根源避免问题的产生;python则是通过限定作用域来解决该问题。

2、编译时: lua编译一个函数时,会为它生成一个原型(prototype) --- 包括 函数体对应的虚拟机指令、函数执行用到的常量、一些调试信息。

   运行时: 每当lua执行一个形如function...end 这样的表达式时,它就会创建一个新的数据对象,其中包含了相应函数原型的引用、环境(environment,用来查找全局变量的表)的引用以及一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。

   即函数是编译期概念,是静态的,而闭包是运行期概念,是动态的。

3、词法定界:当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界。

   闭包的产生:调用了某种类型的外包函数产生的一个实例函数(类似上面的代码示例),这个外包函数满足,它的内嵌函数访问了在它中定义的局部变量。

   闭包组成:外部函数+外部函数创建的局部变量+内部函数(闭包函数)

参考:https://blog.csdn.net/maximuszhou/article/details/44280109

  https://www.cnblogs.com/zzy-frisrtblog/p/5864209.html

  http://blog.chinaunix.net/uid-52437-id-2108789.html

最新文章

  1. 源代码版本管理与项目管理软件的认识与github的注册
  2. Linux CPU负载
  3. C# WinForm自定义控件响应键盘事件
  4. kdbchk: the amount of space used is not equal to block size
  5. asp.net:录入数据库的中文变问号
  6. c/c++动态分配内存和malloc的使用
  7. CentOS 启动提示unexpected inconsistency;RUN fsck MANUALLY
  8. Mustache学习
  9. 14.2.5.5 Change Buffer
  10. gcc manual
  11. B+树的插入、删除(附源代码)
  12. 带你由浅入深探索webpack4(一)
  13. android添加阴影
  14. windows WebStorm常用快捷键记录,常用的都在这儿找扒
  15. Activiti For Eclipse(Mars)插件配置
  16. 七、持久层框架(MyBatis)
  17. Linux之间用SSH传输文件 一行命令实现
  18. Redis在.net中的应用学习
  19. 通过sessionStorage来根据屏幕宽度变化来加载不同的html页面
  20. handsontable-integrations

热门文章

  1. DDoS防御方案
  2. dubbo-集群容错
  3. py4CV例子2汽车检测和svm算法
  4. Node复习
  5. bzoj 2527 Meteors - 整体二分 - 树状数组
  6. day 26 元类
  7. 使用Jenkins构建、部署spring boot项目
  8. 用Navicat for Mysql导入.sql文件
  9. topcoder srm 485 div1
  10. 【做题】agc003E - Sequential operations on Sequence——经典结论