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
lua中的闭包概念的学习笔记的更多相关文章
- Lua中的闭包
[什么是闭包?] 闭包在Lua中是一个非常重要的概念,闭包是由函数和与其相关的引用环境组合而成的实体.我们再来看一段代码: function newCounter() return function ...
- [译] Closures in Lua - Lua中的闭包
原文:(PDF) . 摘要 一等(first-class)函数是一种非常强大的语言结构,并且是函数式语言的基础特性.少数过程式语言由于其基于栈的实现,也支持一等函数.本文讨论了Lua 5.x用于实现一 ...
- [转][译] Closures in Lua - Lua中的闭包
http://www.cnblogs.com/plodsoft/p/5900270.html?utm_source=tuicool&utm_medium=referral 原文:(PDF) . ...
- 两个函数彻底理解Lua中的闭包
本文通过两个函数彻底搞懂Lua中的闭包,相信看完这两个函数,应该能理解什么是Lua闭包.废话不多说,上 code: --[[************************************** ...
- 时间序列算法(平稳时间序列模型,AR(p),MA(q),ARMA(p,q)模型和非平稳时间序列模型,ARIMA(p,d,q)模型)的模型以及需要的概念基础学习笔记梳理
在做很多与时间序列有关的预测时,比如股票预测,餐厅菜品销量预测时常常会用到时间序列算法,之前在学习这方面的知识时发现这方面的知识讲解不多,所以自己对时间序列算法中的常用概念和模型进行梳理总结(但是为了 ...
- C#同步,异步的理解,包括5.0中await和async(学习笔记)
之前在工作中一直用的是同步线程,就是先进入画面的load事件,然后在里面进行数据库调用的处理.后面又遇到了公司软件中一些比较古老的代码,一开始在那块古老代码中增加机能的时候,我想用到数据库的数据给画面 ...
- Lua中的环境概念
[前言] Lua将其所有的全局变量保存在一个常规的table中,这个table称为“环境”.这种组织结构的优点在于,其一,不需要再为全局变量创造一种新的数据结构,因此简化了Lua的内部实现:另一个优点 ...
- javascript中的闭包(Closure)的学习
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面是我在网上通过学习阮一峰老师的笔记,感觉总结很不错,特记录于此. 一.变量的作用域 要理解 ...
- java中有关socket通信的学习笔记
最近做的项目中使用到了一些基于java的socket长连接的一些功能,用来穿透有关行业的网闸.用到了也就学习了一下,下面是对学习内容的一个笔记,记录一下也希望有兴趣的同学可以参考一下,加深对javas ...
随机推荐
- ORA-30377 MV_CAPABILITIES_TABLE not found
Cause: You have used the DBMS_MVIEW.EXPLAIN_MVIEW() API before you have defined the MV_CAPABILITIES_ ...
- How to Conduct High-Impact Research and Produce High-Quality Papers
How to Conduct High-Impact Research and Produce High-Quality Papers Contents From Slide Russell Grou ...
- 变参标准函数的重新封装,如printf
方法一: #include <stdio.h> #include <stdarg.h> void my_trace(const char *cmd, ...) { printf ...
- Codeforces Round #439 (Div. 2) Problem A (Codeforces 869A) - 暴力
Rock... Paper! After Karen have found the deterministic winning (losing?) strategy for rock-paper-sc ...
- C语言动态链表数据结构
链表的操作增删改查 typedef int DATA; struct SNode { DATA data; SNode* pNext; }; SNode* g_head=NULL;//全局变量 //从 ...
- 牛客网数据库SQL实战(21-25)
21.查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序CREATE TABLE `employees` (`emp_no` i ...
- 【Python30--文件系统】
一.模块 定义:模块是一个包含所有定义的函数和变量的文件,后缀名是.py.模块可以被别的程序引用,以使用该模块中的函数等功能 >>> secret = random.randint( ...
- iOS开发 -------- UITableView的编辑
一 核心API Class: UITableView Delegate: UITableViewDataSource, UITableViewDelegate 涉及到的API: 插入和删除 1 /** ...
- Python3 tkinter基础 Button text,fg 按钮上显示的文字 文字的颜色
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- 【server.properties】kafka服务设置
每个kafka broker中配置文件server.properties默认必须配置的属性如下: broker.id=0 num.network.threads=2 num.io.threads=8 ...