第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目


19.1 – 数组大小

在 Lua 中,我们经常假设数组在其第一个 nil 元素之前结束。此约定有一个缺点:我们不能在数组中使用 nil。对于某些应用程序来说,此限制并不是障碍,例如当数组中的所有元素都具有固定类型时。但有时我们必须允许在数组中使用 nil。在这种情况下,我们需要一种方法来为数组保留显式大小。

表库定义了两个函数来操作数组大小:getn(返回数组的大小)和 setn(设置数组的大小)。如前所述,有两种方法可以将属性与表关联:要么我们将属性存储在表的字段中,要么使用单独的(弱)表进行关联。两种方法各有优缺点;因此,table 库同时使用了这两种方法。

通常,调用 table.setn(t, n) 会在内部(弱)表中将 tn 关联,而调用 table.getn(t) 会检索与该内部表中的 t 关联的值。但是,如果表 t 有一个带有数字值的字段 "n",则 setn 会更新此值,而 getn 会返回此值。getn 函数仍然有一个最后的选择:如果它无法使用任何这些选项获取数组大小,它将使用朴素的方法:遍历数组,寻找其第一个 nil 元素。因此,您始终可以在数组中使用 table.getn(t) 并获得合理的结果。请参阅示例

    print(table.getn{10,2,4})          --> 3
    print(table.getn{10,2,nil})        --> 2
    print(table.getn{10,2,nil; n=3})   --> 3
    print(table.getn{n=1000})          --> 1000
    
    a = {}
    print(table.getn(a))               --> 0
    table.setn(a, 10000)
    print(table.getn(a))               --> 10000
    
    a = {n=10}
    print(table.getn(a))               --> 10
    table.setn(a, 10000)
    print(table.getn(a))               --> 10000

默认情况下,setngetn 使用内部表来存储大小。这是最干净的选项,因为它不会用额外的元素污染数组。但是,n 字段选项也有一些优点。Lua 核心使用此选项来设置具有可变数量参数的函数中 arg 数组的大小;因为核心不能依赖于库,所以它不能使用 setn。此选项的另一个优点是,我们可以在数组的构造函数中直接设置其大小,就像我们在示例中看到的那样。

即使你知道大小在字段 n 中,最好使用 setngetn 来操作数组大小。table 库中的所有函数(sortconcatinsert 等)都遵循此做法。实际上,setn 改变字段 n 值的可能性仅是为了与 Lua 的旧版本兼容。此行为在语言的未来版本中可能会更改。为了安全起见,请不要假定此行为。始终使用 getn 来获取由 setn 设置的大小。