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