{为了要 遇见你 我连呼吸都反复练习}
闭包//
闭包:是由一个函数和该函数会访问到的非局部变量(upvalue)组成的,其中非局部变量(non-local var)是指不是在局部作用范围内定义的一个变量,但同时又不是全局变量,主要应用在嵌套函数和匿名函数里。每个闭包都有一个相应函数原型的引用以及一个数组,数组中每个元素都是一个对upvalue的引用,可以通过该数组来访问外部的局部变量(outer local variables)。
eg:
function foo(n)
local function f()
print(n)
end
return f
end
t1 = f(2016)
t1() --print 2016
t2 = f(2017)
t2() --print 2017
在运行时,每当Lua执行一个形如function...end 这样的表达式时,他就会创建一个新的数据对象,其中包含了相应函数原型的引用及一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。由此可见,函数是编译期概念,是静态的,而闭包是运行期概念,是动态的。t1和t2的值严格来说不是函数而是闭包,并且是两个不相同的闭包,而每个闭包能保有自己的upvalue值。upvalue实际指的是变量而不是值,这些变量可以在内部函数之间共享,即upvalue提供一种闭包之间共享数据的方法
eg:
function Fun(n)
local function foo1()
print(n)
end
local function foo2()
n = n + 10
end
return foo1,foo2
end
f1,f2 = Fun(2016)
f1() -- 打印2016
f2()
f1() -- 打印2026
f2()
f1() -- 打印2036
在闭包自己堆栈上为找到对应的变量n的时候,会到他们的外包的闭包的upvalue引用数组中去找,并把找到的引用值拷贝到自己的upvalue引用数组中!注意是引用不是拷贝!所以外闭包的n会被修改
应用:
1.当作高阶函数参数传递
2.实现迭代器
function iterator(t)
local idx = 0
return function()
idx = idx + 1
return t[idx]
end
end
t = {10, 20, 30}
itr = values(t)
while true do
local element = iterator()
if element == nil then break end
print(element)
end