Lua基础(十一)闭包

一    函数是第一类值的理解

0)和其它'常见类型'的值'数值、字符串'具有'同等权限'

1)将某个函数'保存到变量中'-->'全局、局部'变量

补充:它可以存储在"变量"或"table"里

2)函数'作为参数'传递给其他函数

补充:作为'实参'或'高阶函数'传递给其他函数调用

3)将某个函数作为'其它函数的返回值'返回

二    函数定义等价方式

三    lua闭包

(1)闭包的由来

JS闭包

原因:lua中允许函数的'嵌套定义[define]',并且在'内嵌函数'中使用了'外包函数'中定义的'局部'变量

补充: C语言'static'有点这个'意味'

备注: c、'c#'就'不允许'函数的嵌套定义,但是'允许'函数的"嵌套调用(call)"

(2)函数嵌套定义

需求:将函数存储在'表字段' -->'匿名函数的味道'

(3)闭包的定义

'函数'可以访问他'被创建时'所处的'上下文环境',这被称为'闭包'

 闭包:一个闭包就是'一个函数'外加能够'使该函数正确访问非局部变量'所需的其他'机制'

 一个函数中'嵌套子函数',子函数可以'使用父函数中的局部变量',这种行为就是"闭包"

 闭包 = 函数 + 引用环境

+++++++++++++++++"关键词"+++++++++++++++++

function、closure['闭包']、upvalue['非局部变量']、内嵌('inner')函数,外包('enclosing')函数

(4)闭包的几个概念 

①    upvalue

1. upvalue: "非局部"变量,"实际"指的是'变量'而'不是值'

  备注:upvalue称该'内嵌函数'的'外部局部变量'(external local variable)

2. 理解为'C语言基础'函数内部定义的"静态(static)变量"

3. upvalue的"[定义]":一定是'外部函数'定义的的local'局部变量',且在'内部'函数'调用过'

++++++++++++++"更具体的描述"++++++++++++++

1) '外部函数'定义的'local'局部变量

2)  且在'内部函数中可以被调用'

++++++++++++++++'匿名函数访问一个非局部变量'++++++++++++++++

理解:站在'匿名函数'的角度中,count'既不是'全局变量'也不是'局部变量,而'是非局部变量'-->'upvalue'

②    词法定界

词法定界(lexical scoping):'内嵌函数'可以访问'外包函数'已经创建的'所有局部变量'

这种'特性[机制]'称之为'词法定界'
​
特性:一个函数A'内嵌套'另一个'函数B'的时候,'内函数B'可以访问'外部函数A'的'局部变量'

可以'访问'的原因: 内嵌与外包关系是'允许'传递的,架起一座'桥梁'

③    闭包函数一般函数区别

1.  闭包只是在'形式和表现上'像函数,但实际上'不是函数'

2.  函数'只有一个实例',定义后'逻辑就确定了',不会执行时发生变化

④    闭包的功能

⑤    局部函数

'局部函数'可以理解为在'当前作用域有效的函数',可以用'local变量来引用'一个函数

'局部函数'对于'包'而言尤其重要

思考:局部函数的'作用域'?

++++++++++++++'应用场景'++++++++++++++

局部函数只能在'函数所在的文件中'引用;好处:可以'屏蔽细节'

  

⑥    案例讲解

1)案例1

特殊: return '嵌套' return --> "返回"的是'局部函数'

​补充:new_count()中传入的参数也是'局部变量',类似于在'外部函数内'定义一个'local变量'

核心点:当执行完'c1 = new_counter()'后,局部变量'count'的生命'本该'结束,但因为它已经成了内嵌函数c(它又被赋给了变量g1)的upvalue,所以它仍然能以'某种形式'继续"存活"下来

1.  内嵌函数定义在"count = count + 1"这条语句'之前'

2.  upvalue实际是'local局部'变量-->"count",是保存在'函数堆栈框架'上(stack frame)的

3.  所以只要upvalue还'没有离开'自己的作用域,它就一直'生存'在"函数堆栈上"

4.  这种情况下,闭包将通过'指向'堆栈上的upvalue的引用来'访问'它们

5.  一旦upvalue'即将离开'自己的作用域(这也意味着它马上要从堆栈中消失),闭包就会为它'分配空间'并保存当前的值,以后便可通过'指向新分配空间的引用'来'访问'该upvalue

6.  当执行到c1的"count = count + 1"时,闭包已经'创建'了,但是count并'没有离开'作用域,所以闭包仍然'引用'堆栈上的count

7.  当'return count'完成时,count即将'结束'生命,此时闭包便将'count(已经是1了)'复制到自己'管理的空间'中以便将来访问

2)案例2

常见: 单层return,还是'返回局部函数'

3)案例3 

upvalue通过'外层函数'传递 --> n

⑦    应用场景

闭包:是数据和行为的"结合体",就好比'C++中的类',这样就使得闭包具有较好的'抽象能力'.

应用场景: 在某些场合下,我们需要'记住'某次调用完成以后'数据的状态' --> lua闭包能'完成'该功能.

备注:C语言的static类型的变量,每次'调用'完成以后,static类型的变量并'不会被清除'.

⑧    参考链接 

技术:Lua语言中'只有闭包而没有函数',函数本身只是'闭包的一种原型'

Lua的闭包详解

闭包函数

lua闭包的终级理解

lua高级扩展

lua闭包浅析及项目应用

⑨    小结

效果上: 按照C语言的'static'来理解;由于'upvalue'也是个局部变量,也只能在'作用域内'访问,这也是return的'局部函数'的原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值