深入函数
在Lua中,函数是作为第一类的对待的,即,可以存储到变量,可以作为返回值,可以作为函数的形参
事实上,在Lua中,函数都是匿名函数,所谓的函数名其实是持有这个函数的变量,
如
function foo(x)
return 2*x;
end
和
foo=function (x) return 2*x end
是等价的
closure 闭合函数
这个概念花了有点久的时间才弄清楚
闭合函数是指 一个函数之中的内部函数,使用了该函数的局部变量,那么这个局部变量的值不会随着内次调用而初始化
即 函数+局部变量+调用了局部变量的内部函数=闭合函数
例如
fuction addNumber()
local i=0; //局部变量
return funtion () //内部函数
i=i+1; //使用了局部变量
return i;
end;
end
adn=addNumber();
print(adn()) =>1
print(adn()) =>2
addNumber中的局部变量i并没有在每次调用的过程中重新置0;这种用法可以用于迭代器之中,或者一连串类似的但是变动不大的操作中
另外,当另外一个变量持有这个参数的时候,函数会赋予参数新的闭合函数
如
adn=addNumber();
adc=addNumber();
print(adn()) =>1
print(adc()) =>1
print(adn()) =>2
同时因为函数的第一类特性,可以用这种方式来给函数重新定义
例如
do
local oldSin=math.sin;
math.sin=funtion (x)
return oldSin(2*x)
end
end
先将旧的函数赋值给一个变量,然后使用新的实现方式来实现,那么这样就避免了直接调用旧的函数,必须通过新的函数来访问旧的函数,因为函数的调用本身是没有限制的,这个就可以创造一个限制的条件
以为函数的第一类特性,函数甚至可以做为table的元素
例如
tbl={}
tbl.foo=funtion (x,y) return x+y end
tbl.goo=funtion (x,y) return x*y end
或者
funtion tbl.foo(x,y) return x+y end
funtion tbl.goo (x,y) return x*y end
尾调用
function f() return g() end
当一个函数的返回值是另外一个函数时,且在调用结束后没有其他操作,那么这一操作不会耗费栈空间,即,不会存储尾函数的的空间,因为不会产生多余的空间,所以在使用递归的时候不用担心递归次数过多而导致栈溢出