作者:手机用户2502920645 | 来源:互联网 | 2023-08-15 15:49
1.尾调用
尾调用简单来说就是当一个函数执行完之后,没有其他事干了,调用另外一个函数,这就是尾调用,如下代码
local eat;
local drink;
eat = function(food) 非全局函数print( "eat food" )return drink();
enddrink = function (milk) 全局函数print( "drink milk" )return "drink milk" ;
endeat();
原理:
lua支持尾调用消除(tail-call elimination)这一特性。
尾调用:当一个函数是另一个函数的最后一个动作时,该调用就是一条尾调用。
尾调用消除:当在进行尾调用时不消耗任何栈空间,这种实现就称为尾调用消除。
function f(x) return g(x) end
当程序执行完g(x)之后,程序就不需要回到f()这个函数了,因为已经无事情可做了,这时程序也不需要保存任何关于f()函数的栈信息了。当g返回,程序的控制权直接返回到调用f的那个点上。
正是这个尾调用消除特性,使得一个程序可以拥有无数嵌套的尾调用,而不会造成栈溢出,例如:
function foo(n)
if n>0 thenreturn foo(n-1) end
end
一直可以调用
不是正确的尾调用如下例子:
function f()a(x)return t(x)+1
end
这个f()函数没有执行完,还有一个+1的动作,所以不能算是尾调用
2.闭包
所谓闭包就是一个局部的变量被另外一个函数用到,生命周期延长,这就是闭包。如下例子:
local sleep;
local wakeUp;
sleep = function ( ... )print( "sleep")local time = 3; --[[函数闭包--]]return function(timer)time =time + 1;return "我睡了" .. time .."小时";end
end
local r = sleep();
上面的案例就形成了闭包,time是局部变量,本来该函数执行完之后,就销毁,但它没有, time被另外一个函数用到,它的生命周期延长,它已经属于一个非局部变量,但又不是全局变量。这样就是一个闭包的显著特点。
如果还是不懂的话,可以看 http://www.2cto.com/kf/201503/382691.html这个网址,上边说的很详细
再加深一点难度
function zsg( ... )local i = 20return function ( ... )i=i+1return iend
endlocal fun = zsg()
print(fun())
print(fun())
print(fun())
输出结果为:21,22,23
对于闭合函数,属于它的非局部变量,并不是在调用它临时产生的,而是和它一起存在的,所以每次调用闭合函数,非局部变量的值不会被重置
扩展
当一个函数调用另外一个局部的函数时,这个局部函数必须在调用那个函数之前声明,否则会出错,例如下边代码
错误的代码
local eat;
eat = function() print( "eat food" )return drink();
end
local drink=function ( ... )print("drink")
end
eat()
正确的代码
local eat
local drink
eat = function() print( "eat food" )return drink()
end
drink=function ( ... )print("drink")
end
eat()
或者可以定义成全局的
博主链接:
http://blog.csdn.net/qq131530624/article/details/53557294