·070函数作为Lua的第一类值,像string和number类型的变量一样也可以有全局函数和局部函数之分。局部函数包括作为table的域的函数(如math.sin和os.time等)和使存放在局部变量中的函数(如local add = function(x, y) return x + y end)
·071作为table的域的函数可按如下几种方式创建:
1)
lib = {}
lib.add = function(x, y) return x + y end
lib.minu = function(x, y) return x - y end
2)
lib = {add = function(x, y) return x + y end, minu = function(x, y) return x - y end}
3)
lib = {}
function lib.add(x, y) return x + y end
function lib.minu(x, y) return x - y end
·072对于存放在局部变量中的函数(即局部函数),它只在其chunk内可见。因此若你在Shell中按如下方式定义局部函数:local add(x, y) return x + y end。结果是再也无法使用它了,因为在Shell中,一行代码就是一个chunk(除非这行代码被包含在了控制语句或do...end中了)。
·073你可以在一个Lua脚本中按如下形式书写多个局部函数并相互调用,因为一个Lua脚本被看做是一个chunk,这样局部函数在整个脚本中都是可见的:
--Script name: test.lua
local add = function(x, y)
return x + y
end
local function show()
print(add(1, 1999)) --局部函数add在这里是可见的
end
minu = function(x, y) --将函数存放在此局部变量中即得到局部函数
return x - y
end
local function fact(n)
if n == 0 then
return 1
else
return n * fact(n - 1)
end
end
由于在以上的代码中递归函数fact为采用先声明后定义的方式,Lua解释器就不会知道fact是一个局部函数,因此它会查找全局函数fact,从而导致错误。正确的代码如下:
local fact
function fact(n)
if n == 0 then
return 1
else
return n * fact(n - 1)
end
end
·075当函数的最后一个动作是调用另一个函数时,我们称这种调用是尾调用。例如:
function creat_all()
--实现代码
return clean() --最后一个动作仅仅是调用了clean函数
end
尾调用有点像在函数的最后使用了C中的goto语句。
·076尾调用的好处是当被调用的函数结束时,程序不需要返回调用者中。因此程序就不需在栈中保存调用者的任何信息(用于返回调用者处的信息),即不适用额外的栈内存。这意味着递归的层次可以无限深而不导致栈内存溢出。例如:
function fun(n)
if n > 0 then
return fun(n - 1)
end
end
此示例中,无论n为何值均不会导致栈内存溢出。
·077判断一下情形是否为尾调用:
a)
function fun()
g(x)
return
end
b)
function fun()
return g(x) + 1
end
c)
function fun()
return x and g(x)
end
d)
function fun()
return (g(x))
end
e)
function fun()
return lib.add(math.sin(0.5) + 2 ^ 3 - 12)
end