第一版是為 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍有一些區別。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買這本書,您還可以幫助 支持 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 設定的大小。