1.什么是闭包
支持闭包特性通常需要一个嵌套函数 , 通过执行嵌套函数来改变所在父函数的局部变量状态 , 父函数保存调用上下文状态 , 而嵌套函数负责修改状态的改变 . (简单来说就是得支持函数嵌套)
下面就是一个Lua闭包:
function counter() local cnt = 0 --返回匿名函数也是可以的 local Closure = function() cnt=cnt+1 print("print:"..cnt) end return Closure end function main() local Closure = counter() Closure() --print:1 Closure() --print:2 Closure() --print:3 end
2.闭包的作用
class Person { private String name; public String getName() { return name; } }
通过上面的方式可以获取到一个类内部的私有属性,同样的,在lua中可以通过某个方法来获取这个方法的局部变量,然后通过这个方法内的方法来读取想要的变量值。
function func3() local num3 = 44 function func4() return num3 end return func4 end local func = func3(); print(func())
解释:
1.在外部无法获取到func3内部的局部变量,但是func3内部的局部方法func4却可以获取到,因此 返回一个func4的引用 ,这样在外部通过这个func4就可以获取到func3的内部变量。
2.虽然是绕了一个圈子,但是在方法外部却通过这样一个手段获取到了内部的值。而这个方法内的局部方法func4就叫做闭包,按照很多书上的概念,这个方法搭建了方法内部与方法外部的桥梁,使得在外部也可以任意的获取到方法内部的资源。
3.但是闭包会造成变量在内存中持久占用,因此会有一定的性能问题,最好不要轻易使用,即便使用也要在恰当的实际进行释放。
--以下用cocos2dx中的Lua来举例... --2dx通过tolua++把类方法导出 --举例api --按钮响应回调函数格式为: --luaFunc(event) --event为触摸按下,触摸移动,触摸离开等事件 --lua中的API为: --UIButton::addListenHandler(luaFunc) --实际需求是我按钮按下时,我需要改变按钮自身的纹理...此时回调中却没有按钮本身的对象(sender),怎么办呢? --利用闭包就轻松解决了 --下面是LUA实战例子:一个testUI的页面类 local testUI = testUI or {} local testUI:onBtnClick(sender,event) --可获取的参数有:隐藏的self,btn,event end function testUI:initButton() local btn = UIButton:create() --重点来了 btn:addListenHandler( function(event) --使用闭包把self,btn都传进去了.... self:onBtnClick(btn,event) end ) end return testUI