今天继续学习函数的高级内容:web
6. More about Functions
1)函数名是变量,能够赋值,传递,做为函数的返回值
如图:

2)匿名函数:
Lua容许匿名函数:如
f = function (x) return 2*x end -->建立了一个匿名函数,并将函数赋值给变量f
3)高级函数:
在Lua中,用其余函数的名称做为输入参数的函数,叫作高级函数。
做为输入参数的函数名,和通常的变量使用方式相同, 如:
或者:

4)闭包:
函数嵌套时:内部函数能够访问外部函数的变量,这个变量称做外部的局部变量:external local variable 或者 upvalue
如图所示:

i是Count的局部变量,在内嵌的匿名函数中被访问,每次递增一
注意:
(1)直接打印print(Cn()),打印的是内嵌函数的地址。
(2)c1 = Cn(),表示将Cn的内嵌函数付给了c1。和 c1 = Cn彻底不一样含义。
(3)c1只是Cn()内嵌函数的变量,但其中用到了Cn的局部变量i,则经过Lua的闭包机制,在c1中创建了一个i的实例。
(4)建立了两个Cn()的实例,c1和c2,他们拥有各自独立的外部局部变量i,他们的计数是相互独立的。
从技术上讲,闭包是值,而不是函数,有点相似于创建了一个类的实例,其中的upvalue都有本身的一个实例。
闭包技术能够做为一种沙箱实现,来建立安全的环境,把不安全代码放在一个闭包中,来限制访问的方式。
5)表的函数:
(1)对表,能够添加表对应的函数,如:
Lib = {}
Lib.foo = function (x,y) return x+y end
lib.goo = function (x,y) return x-y end
或者
Lib = {
foo = function (x,y) return x+y end,
goo = function (x,y) return x-y end
}
或者
Lib = {}
function Lib.foo(x,y) return x+y end
function Lib.goo(x,y) return x-y end
这种方式相似于C语言中给结构体加函数的方式。
6)局部函数:
将函数赋值给局部变量,能够限制函数的方位范围。如:
local f = function(x) return 2*x end 则,函数只能在f的做用域中使用。
或者,
local function f(x) return 2*x end 和上述的做用相同
对递归函数须要先声明局部函数,不然Lua会找不到相应的函数,如:
local fact
fact = function (n)
if n <= 0 then return 1
else return n*fact(n-1) end
end
7)尾调用(尾递归 Tail Calls)
function f()
return g()
end
当调用g()后不须要返回f(),则系统不须要保存f()的上下文,这种状况就称为尾调用。
这时,Lua不会再增长额外的栈来放置被调用的函数g(),在递归时能有效的防止栈溢出。
如:
function f(n)
if n > 0 then return f(n-1) end
end
这时不论n多大,Lua调用时都不会将f层层加栈。
能够讲尾调用当作一个goto语句,而不是通常的函数加栈调用方式。