lua函数具有两大特征:函数作为第一类值,函数具有特定的词法域(Lexical Scoping)
所谓第一类值:代表函数和其他传统类型的值是等价的(例如数字和字符串),函数可以同他们一样存储在变量,table中,可以作为实参传递,可以作为函数返回值。
对于第一类值,需要讲明,函数和其他值一样都是匿名的,是没有名字的。而我们平时所说的函数名,如print(),都只是一种语法糖,一个持有某个函数的变量。
例如:
function foo(x) return 2*x end --->等价于 foo = function(x) return 2*x end
函数定义实际上是一条赋值语句。这条语句先创建一个类型为函数的值,然后将其赋值给一个变量。
我们将表达式“function (x) <body> end”视为函数的构造式,又被称其为匿名函数,在某些特殊情况下,我们会用到匿名函数。
特定的词法域(Lexical Scoping):指一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数的变量。
闭合函数(closure)
由于词法域的原因,当一个函数写在另一个函数内部,而这个内部函数可以访问外部函数的局部变量,这个被访问的局部变量既不是全局的也不是局部的,被称为非局部的变量(non-local variable).
所以闭合函数就是这个内部函数加上该函数需要访问的所有的非局部变量的函数。
关于闭包的实现原理,推荐以下博客http://blog.youkuaiyun.com/maximuszhou/article/details/44280109。
关于闭包,有几个需要注意的地方:
e.g.
function newCounter()
local i = 0;
return function()
i = i+1
return i
end
end
c = newCounter() -- newCounter返回匿名函数赋予变量c,此时c是一个闭包,同时拥有一个upvalue值
print(c()) -->1
print(c()) -->2 --匿名函数再次访问闭包中的upvalue值,使其加1.
--注意,如果再次调用newC