第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但还是存在一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还将帮助支持 Lua 项目。
用 Lua 编程 | ||
第二部分。表和对象 第 15 章。包 |
有时,一个包会导出其所有名称;也就是说,该包的任何客户端都可以使用它们。然而,通常情况下,在一个包中拥有私有名称很有用,也就是说,只有该包本身才能使用的名称。在 Lua 中,一种方便的方法是将这些私有名称定义为局部变量。例如,让我们向我们的示例中添加一个私有函数,用于检查一个值是否是有效的复数。我们的示例现在看起来像这样
local P = {} complex = P local function checkComplex (c) if not ((type(c) == "table") and tonumber(c.r) and tonumber(c.i)) then error("bad complex number", 3) end end function P.add (c1, c2) checkComplex(c1); checkComplex(c2); return P.new(c1.r + c2.r, c1.i + c2.i) end ... return P
这种方法的优点和缺点是什么?一个包中的所有名称都存在于一个单独的名称空间中。包中的每个实体都明确标记为公共或私有。此外,我们拥有真正的隐私:私有实体在包外不可访问。这种方法的一个缺点是,在同一个包内访问其他公共实体时,它很冗长,因为每次访问仍然需要前缀P
。一个更大的问题是,每当我们将函数的状态从私有更改为公共(或从公共更改为私有)时,我们都必须更改调用。
有一个有趣的解决方案可以同时解决这两个问题。我们可以将包中所有函数声明为局部函数,然后将它们放入要导出的最终表中。按照这种方法,我们的complex
包将如下所示
local function checkComplex (c) if not ((type(c) == "table") and tonumber(c.r) and tonumber(c.i)) then error("bad complex number", 3) end end local function new (r, i) return {r=r, i=i} end local function add (c1, c2) checkComplex(c1); checkComplex(c2); return new(c1.r + c2.r, c1.i + c2.i) end ... complex = { new = new, add = add, sub = sub, mul = mul, div = div, }
现在,我们不需要对任何调用添加前缀,因此对导出函数和私有函数的调用是相等的。包的末尾有一个简单的列表,明确定义了要导出的名称。大多数人觉得将此列表放在包的开头更自然,但我们无法将列表放在顶部,因为我们必须首先定义局部函数。
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |