lua基本知识点3

1.尾调用

尾调用简单来说就是当一个函数执行完之后,没有其他事干了,调用另外一个函数,这就是尾调用,如下代码

local eat;
local drink;
eat = function(food)			非全局函数
	print( "eat food" )
	return drink();
end

drink = function (milk)			全局函数
	print( "drink milk" )
	return "drink milk" ;
end

eat();


原理:
lua支持尾调用消除(tail-call elimination)这一特性。

尾调用:当一个函数是另一个函数的最后一个动作时,该调用就是一条尾调用。

尾调用消除:当在进行尾调用时不消耗任何栈空间,这种实现就称为尾调用消除。

function f(x) return g(x) end

当程序执行完g(x)之后,程序就不需要回到f()这个函数了,因为已经无事情可做了,这时程序也不需要保存任何关于f()函数的栈信息了。当g返回,程序的控制权直接返回到调用f的那个点上。


正是这个尾调用消除特性,使得一个程序可以拥有无数嵌套的尾调用,而不会造成栈溢出,例如:

function foo(n)
if n>0 then
  return 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 = 20
	return function ( ... )
		i=i+1
		return i
	end
end

local 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

猜你喜欢

转载自blog.csdn.net/qq131530624/article/details/53557294