闭合函数(closure)
看Lua程序设置这本书的时候,其实感觉也就Lua也就那样,直到看到闭合函数这一个块
首先来说说函数,函数在lua中属于第一类值,
其实对于函数而言,function a() ... end 和 a = function()...end 是等价的,
一个函数的定义实际上就是一条赋值语句,这条语句首先创建一个函数类型的值,然后再把这个值赋值给这个函数的变量。
可以把 function()...end 看成是一个函数的构造式,就和table的构造式没什么区别。
function()...end 所以一个匿名函数,a = function()...end实际操作就是将这个匿名函数赋值给了a,所以a就是这个函数名,等同于function a()...end
说完函数,在说说一个概念,非局部变量,
什么叫非局部变量呢,书面意思,就是说他不是一个局部的变量,但他也不是一个全局的变量
例如:
function newCount()
local i = 0 -- 局部变量 i
return function() --匿名函数
i = i + 1 --非局部变量 i
end
end
对于上面那个函数中那个返回的匿名函数来说,他里面的那个变量i,他并不是一个局部的变量,但他也不是一个全局的变量,对于这种变量,lua给他的定义就是 非局部变量
c1 = newCounter()
print(c1())
print(c1())
c2 = newCounter()
print(c2())
print(c1())
print(c2())
他的输出结果为
为什么第二次的c1()的结果会是2呢?这就是之前强调的 , 函数是lua的第一类值
就如同C++的int a = 0 ,是直接在栈中开辟一块内存来存放a的值,直到释放,
其实这个也一样,c1 = newCounter() 其实就是开辟了一个栈空间,之后的操作一直都是在这个栈里面进行操作的,
也就是说第一次打印c1的时候,i 从 0 变成了 1,然后继续打印c1,你会发现,i 变成2了,这是因为 c1所开辟的那个栈空间并没有释放,你的一切操作还是在原来的栈空间中操作的,栈空间中的i在第一次打印的时候就已经变成1了,所以再次打印的时候,栈空间中的i就变成了2
而c2 = newCounter()之后打印c2()结果为1,那是因为c2 = newCounter()又在栈中开辟了一个新的空间,所以他们里面的i的值其实是不一样的值