一、lua函数赋值与函数调用
在lua中函数名也是作为一种变量出现的,即函数和所有其他值一样都是匿名的,当要使用某个函数时,需要将该函数赋值给一个变量,这样在函数块的其他地方就可以通过这个变量来调用这个函数。
foo = function (x) return * end; --标准用法,函数赋值
function foo(x) return * x end; --常见用法,等价于上面
如果函数只是作为另外函数的参数或者子函数块时,即不涉及到外部调用时,不需要赋值(命名),可以直接使用
network = {
{name = "lilei", ip = "192.168.1.2"},
{name = "lucy", ip = "192.168.2.3"},
}
table.sort(network, function (a, b) return (a.name > b.name) end)) --作为函数参数的匿名函数 function derivative(f, delta) --函数赋值
delta = delta or 1e-4
return funciton (x) --作为子函数块的匿名函数
return (f(x + delta) - f(x)) / delta
end
end c = derivative(math.sin) --函数调用
print(math.cose(), c())
二、尾调用
一个函数调用是另一个函数的最后一个语句的时候,通常情况下是作为return语句返回的函数调用 eg:function f(x) return g(x) end, 这个函数中的g(x)属于尾调用,符合尾调用的格式为 return <func>(para) 。在尾调用的情况下,被调函数执行完就不用返回调用者的函数栈,也就是讲在进行尾调用的时候,调用者的函数栈就可以释放掉了,这对于那些需要进行递归调用的场景非常契合。eg:function f(x) g(x) end 这个函数中的g(x)不属于尾调用。
三、closure
一个closure就是一种可以访问其外部嵌套环境中的局部变量的函数,对与closure而言,这些变量就可以用于在成功调用之间保持状态值,从而使closure可以记住他在一次遍历中所在的位置。为了创建一个closure,必须创建closure所用到的“非局部变量”,因此一个closure结构通常涉及到两个函数:closure本身和一个用于创建该closure的工厂函数。eg:
function newCounter()
local i =
return function()
i = i +
return i
end
end
c1 = newCounter()
c2 = newCounter()
--函数调用,由于返回值是一个匿名函数,所以就相当于将newCounter函数中的匿名函数赋值给了c1、c2 print(c1()) --
print(c2()) --
print(c1()) --
--由于i属于“非局部变量”,在给c1、c2赋值时,i已经被初始化为0,此时的i在c1、c2内部相当于C语言中函数内部的static变量,所以会出现上述的结果
注:部分内容引自《Lua 程序设计》以及 http://www.cnblogs.com/Kelvinshere/archive/2012/09/10/closure.html