第一版是針對 Lua 5.0 編寫的。雖然對於後續版本來說仍然有很大關聯,但有一些不同之處。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您還可以幫助 支援 Lua 專案。
![]() |
Lua 中的 編程 | ![]() |
第一部分。語言 第 2 章。類型和值 |
表格類型實作關聯陣列。關聯陣列是一種陣列,不僅可以用數字索引,還可以字串或語言中的任何其他值(nil 除外)索引。此外,表格沒有固定大小;您可以動態地向表格中新增任意數量的元素。表格是 Lua 中的主要(事實上是唯一的)資料結構化機制,而且功能強大。我們使用表格以簡單、統一且有效率的方式表示一般陣列、符號表、集合、記錄、佇列和其他資料結構。Lua 也使用表格來表示套件。當我們撰寫 io.read
時,我們的用意是「io
套件中的 read
項目」。對於 Lua 來說,這表示「使用字串 "read"
作為鍵值,索引表格 io
」。
Lua 中的表格既不是值也不是變數;它們是物件。如果您熟悉 Java 或 Scheme 中的陣列,那麼您對我們的用意應該有相當程度的了解。但是,如果您對陣列的概念來自 C 或 Pascal,那麼您必須稍微轉換一下思維。您可以將表格視為動態配置的物件;您的程式只會處理它們的參考(或指標)。幕後沒有隱藏的複本或新表格的建立。此外,您不必在 Lua 中宣告表格;事實上,沒有辦法宣告表格。您透過建構式運算式建立表格,其最簡單的形式寫作 {}
a = {} -- create a table and store its reference in `a' k = "x" a[k] = 10 -- new entry, with key="x" and value=10 a[20] = "great" -- new entry, with key=20 and value="great" print(a["x"]) --> 10 k = 20 print(a[k]) --> "great" a["x"] = a["x"] + 1 -- increments entry "x" print(a["x"]) --> 11表格總是匿名的。持有表格的變數與表格本身之間沒有固定的關係
a = {} a["x"] = 10 b = a -- `b' refers to the same table as `a' print(b["x"]) --> 10 b["x"] = 20 print(a["x"]) --> 20 a = nil -- now only `b' still refers to the table b = nil -- now there are no references left to the table當程式中沒有任何表格的參考時,Lua 記憶體管理最終會刪除表格並重複使用其記憶體。
每個表格都可以儲存具有不同類型索引的數值,而且會根據需要容納新項目而擴充
a = {} -- empty table -- create 1000 new entries for i=1,1000 do a[i] = i*2 end print(a[9]) --> 18 a["x"] = 10 print(a["x"]) --> 10 print(a["y"]) --> nil請注意最後一行:與全域變數一樣,如果表格欄位未初始化,則會評估為 nil。也與全域變數一樣,您可以將 nil 指定給表格欄位以刪除它。這並非巧合:Lua 將全域變數儲存在一般表格中。有關此主題的更多資訊,請參閱 第 14 章。
若要表示記錄,請使用欄位名稱作為索引。Lua 提供 a.name
作為 a["name"]
的語法糖,支援這種表示方式。因此,我們可以更簡潔地撰寫前一個範例的最後幾行,如下所示
a.x = 10 -- same as a["x"] = 10 print(a.x) -- same as print(a["x"]) print(a.y) -- same as print(a["y"])對於 Lua 來說,這兩種形式是等效的,可以自由地相互替換;但對於人類讀者來說,每種形式可能表示不同的意圖。
初學者常犯的錯誤是將 a.x
與 a[x]
混淆。第一種形式代表 a["x"]
,也就是由字串 "x"
索引的表格。第二種形式是由變數 x
的值索引的表格。請看差異
a = {} x = "y" a[x] = 10 -- put 10 in field "y" print(a[x]) --> 10 -- value of field "y" print(a.x) --> nil -- value of field "x" (undefined) print(a.y) --> 10 -- value of field "y"
要表示一個傳統陣列,您只需使用具有整數鍵的表格。沒有辦法宣告它的尺寸;您只需初始化您需要的元素
-- read 10 lines storing them in a table a = {} for i=1,10 do a[i] = io.read() end當您迭代陣列的元素時,第一個未初始化的索引將導致 nil;您可以使用這個值作為哨兵來表示陣列的結束。例如,您可以使用以下程式碼列印上一個範例中讀取的行
-- print the lines for i,line in ipairs(a) do print(line) endLua 基本函式庫提供
ipairs
,這是一個方便的函式,讓您可以迭代陣列的元素,並遵循陣列在第一個 nil 元素結束的慣例。
由於您可以使用任何值索引表格,因此您可以從任何您喜歡的數字開始陣列的索引。然而,在 Lua 中慣例是從一(而不是像 C 中的零)開始陣列,而標準函式庫也遵循此慣例。
由於我們可以用任何類型索引表格,因此在索引表格時,我們會遇到與等式中出現的相同細微差別。雖然我們可以用數字 0
和字串 "0"
索引表格,但這兩個值是不同的(根據等式),因此表示表格中的不同位置。同樣地,字串 "+1"
、"01"
和 "1"
都表示不同的位置。當對索引的實際類型有疑問時,請使用明確轉換以確保
i = 10; j = "10"; k = "+10" a = {} a[i] = "one value" a[j] = "another value" a[k] = "yet another value" print(a[j]) --> another value print(a[k]) --> yet another value print(a[tonumber(j)]) --> one value print(a[tonumber(k)]) --> one value如果您不注意這一點,您可能會在程式中引入細微的錯誤。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |