一、几个概念
1.1 第一类值
在Lua中函数其他传统类型的值具有相同的权利。
函数可以存储到变量或table中;
可以作为实参传递给其他函数;
可以作为其他函数的返回值。
1.2 词法域
一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数的变量。
1.3 高阶函数(higher-order function)
接收另一函数作为实参的函数,称为“高阶函数”。
table.sort(),接受一个table对其中的元素排序,是一个高阶函数。
代码:
network = {
{name = "lua", ip = "192.168.175.10"},
{name = "c++", ip = "192.168.175.20"},
{name = "erlang", ip = "192.168.175.30"},
{name = "python", ip = "192.168.175.40"},
}
print "before:"
for i,v in pairs(network) do
print(i, v.name, v.ip)
end
table.sort(network, function (a, b) return (a.name > b.name) end)
print "after:"
for i,v in pairs(network) do
print(i, v.name, v.ip)
end
运行结果:
二、closure(闭合函数)
2.1 非局部的变量(non-local variable)
一个匿名函数可以嵌套在另一个函数中,内部的匿名函数可以访问的外部函数的变量,称为“非局部变量”。
2.2 closure闭合函数
一个closure就是一个函数加上该函数所需访问的所有“非局部的变量”。
1. 下面代码,匿名函数访问了一个“非局部的变量”i,该变量用于保持一个计数器。初看上去,由于创建变量i的函数已经(counter())返回,之后每次调用匿名函数时,i都超出了作用范围的。
2. 其实不是,Lua会以closure的概念来正确的处理这种情况。不同的closure,会各自拥有局部变量i的独立实例。
2.2 代码
function counter()
local i = 0
return function ()
i = i + 1
return i
end
end
c1 = counter()
print("c1 --> ", c1())
print("c1 --> ", c1())
c2 = counter()
print("c2 --> ", c2())
print("c1 --> ", c1())
print("c2 --> ", c2())
2.3 运行结果
三、非全局的函数(non-global function)
3.1 局部函数
1. 以下格式递归时报错:
local f = function (<参数>) <函数体> end
2. 以下格式递归时不报错:
local function f (<参数>) <函数体> end
展开为:
local f
f = function (<参数>) <函数体> end
3. 注意间接递归的情况3.2 代码
local fact
fact = function (n)
if n == 0 then
return 1
else
return n*fact(n-1)
end
end
print(fact(3))
四、正确的尾调用函数(proper tail call)
4.1 尾调用消除
当一个函数调用是另一个函数调用的最后一个动作时,该调用才算是一条尾调用。
在Lua中,只有“return <func>(<args>)”这样的调用形式才算是一条尾调用。
functin f(x) return g(x) end
当f调用完g之后,就没有其他的事情可做了。
尾调用后程序不需要保存关于该函数的栈信息了。
Lua得益于这一点,使得“尾调用”时不耗费任何栈空间。 这种实现成为支持“尾调用消除”