第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还将帮助支持 Lua 项目。
![]() |
Lua 中的编程 Lua | ![]() |
| 第一部分。语言 第 6 章。更多关于函数 |
一类函数的一个明显结果是我们不仅可以将函数存储在全局变量中,还可以存储在表字段和局部变量中。
我们已经看到表字段中函数的几个示例:大多数 Lua 库都使用此机制(例如,io.read、math.sin)。要在 Lua 中创建此类函数,我们只需要将函数和表的常规语法放在一起
Lib = {}
Lib.foo = function (x,y) return x + y end
Lib.goo = function (x,y) return x - y end
当然,我们还可以使用构造函数
Lib = {
foo = function (x,y) return x + y end,
goo = function (x,y) return x - y end
}
此外,Lua 还提供了另一种语法来定义此类函数
Lib = {}
function Lib.foo (x,y)
return x + y
end
function Lib.goo (x,y)
return x - y
end
最后一段与第一个示例完全相同。
当我们将函数存储到局部变量中时,我们会得到一个局部函数,即限制于给定范围内的函数。此类定义对于包特别有用:由于 Lua 将每个块作为函数处理,因此块可以声明局部函数,这些函数仅在块内可见。词法作用域确保包中的其他函数可以使用这些局部函数
local f = function (...)
...
end
local g = function (...)
...
f() -- external local `f' is visible here
...
end
Lua 使用语法糖支持此类局部函数
local function f (...)
...
end
递归局部函数的定义中出现了一个微妙的问题。朴素的方法在这里不起作用
local fact = function (n)
if n == 0 then return 1
else return n*fact(n-1) -- buggy
end
end
当 Lua 编译函数体中的调用 fact(n-1) 时,局部 fact 尚未定义。因此,该表达式调用全局 fact,而不是局部 fact。要解决该问题,我们必须首先定义局部变量,然后定义函数
local fact
fact = function (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
现在函数内的 fact 指的是局部变量。当定义函数时它的值无关紧要;当函数执行时,fact 已经具有正确的值。这是 Lua 扩展其局部函数语法糖的方式,因此您可以放心地将其用于递归函数
local function fact (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
当然,如果你有间接递归函数,这个技巧不起作用。在这种情况下,你必须使用显式前向声明的等效项
local f, g -- `forward' declarations
function g ()
... f() ...
end
function f ()
... g() ...
end
| 版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 | ![]() |