第一版是针对 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但有一些区别。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还将帮助支持 Lua 项目。
用 Lua 编程 | ||
第一部分。语言 第 5 章。函数 |
Lua 中的一些函数接收可变数量的参数。例如,我们已经使用一个、两个或更多参数调用过 print
。
现在假设我们想在 Lua 中重新定义 print
:也许我们的系统没有 stdout
,因此 print
不会打印其参数,而是将它们存储在全局变量中以供以后使用。我们可以用 Lua 编写这个新函数,如下所示
printResult = "" function print (...) for i,v in ipairs(arg) do printResult = printResult .. tostring(v) .. "\t" end printResult = printResult .. "\n" end参数列表中的三个点(
...
)表示该函数具有可变数量的参数。当调用此函数时,其所有参数都将收集到一个表中,函数以隐藏参数 arg
的形式访问该表。除了这些参数外,arg
表还有一个额外的字段 n
,其中包含收集到的实际参数数量。
有时,一个函数有一些固定参数和一些可变参数。我们来看一个示例。当我们编写一个将多个值返回到表达式中的函数时,只会使用其第一个结果。但是,有时我们想要另一个结果。一个典型的解决方案是使用哑变量;例如,如果我们只想要 string.find
的第二个结果,我们可以编写以下代码
local _, x = string.find(s, p) -- now use `x' ...另一种解决方案是定义一个
select
函数,该函数从函数中选择一个特定返回
print(string.find("hello hello", " hel")) --> 6 9 print(select(1, string.find("hello hello", " hel"))) --> 6 print(select(2, string.find("hello hello", " hel"))) --> 9请注意,对
select
的调用始终有一个固定参数,即选择器,以及可变数量的额外参数(函数的返回)。为了适应这个固定参数,函数可以在点之前具有常规参数。然后,Lua 将前几个参数分配给那些参数,只有额外的参数(如果有)才会传递给 arg
。为了更好地说明这一点,假设有一个类似这样的定义
function g (a, b, ...) end然后,我们有从参数到参数的以下映射
CALL PARAMETERS g(3) a=3, b=nil, arg={n=0} g(3, 4) a=3, b=4, arg={n=0} g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2}
使用那些常规参数,select
的定义非常简单
function select (n, ...) return arg[n] end
有时,具有可变数量参数的函数需要将所有参数传递给另一个函数。它所要做的就是使用 unpack(arg)
作为参数来调用另一个函数:unpack
将返回 arg
中的所有值,这些值将传递给另一个函数。此用途的一个很好的例子是编写格式化文本的函数。Lua 提供了单独的函数来格式化文本(string.format
,类似于 C 库中的 sprintf
函数)和编写文本(io.write
)。当然,可以轻松地将这两个函数合并为一个函数,只不过这个新函数必须将可变数量的值传递给 format
。这是 unpack
的一项工作
function fwrite (fmt, ...) return io.write(string.format(fmt, unpack(arg))) end
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |