第一版是針對 Lua 5.0 編寫的。雖然在很大程度上仍然適用於後續版本,但有些地方有所不同。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買這本書,您也可以協助 支援 Lua 專案。
![]() |
用 Lua 程式設計 | ![]() |
第 II 部分。表格和物件 第 12 章。資料檔案和持久性 |
在處理資料檔案時,通常寫入資料比讀回資料容易得多。當我們寫入檔案時,我們完全控制正在進行的作業。另一方面,當我們讀取檔案時,我們不知道會讀到什麼。除了正確檔案可能包含的各種資料之外,健全的程式還應該優雅地處理錯誤的檔案。因此,編寫健全的輸入常式總是困難的。
正如我們在 第 10.1 節 的範例中所見,表格建構函式為檔案格式提供了有趣的替代方案。在寫入資料時多花一點功夫,讀取就會變得非常容易。這個技巧是將我們的資料檔案寫成 Lua 程式碼,當執行時,會將資料建置到程式中。使用表格建構函式,這些區塊看起來非常像純文字資料檔案。
照常,讓我們看一個範例來說明。如果我們的資料檔案採用預先定義的格式,例如 CSV(逗號分隔值),我們幾乎沒有選擇。(在 第 20 章 中,我們將看到如何在 Lua 中讀取 CSV。)但是,如果我們要建立檔案以供以後使用,我們可以使用 Lua 建構函式作為我們的格式,而不是 CSV。在此格式中,我們將每筆資料記錄表示為 Lua 建構函式。我們不寫入類似
Donald E. Knuth,Literate Programming,CSLI,1992 Jon Bentley,More Programming Pearls,Addison-Wesley,1990這樣的內容到我們的資料檔案中,而是寫入
Entry{"Donald E. Knuth", "Literate Programming", "CSLI", 1992} Entry{"Jon Bentley", "More Programming Pearls", "Addison-Wesley", 1990}請記住,
Entry{...}
與 Entry({...})
相同,也就是呼叫函式 Entry
,其單一引數為表格。因此,這段先前的資料是 Lua 程式。若要讀取這個檔案,我們只需要執行它,並針對 Entry
提供一個明智的定義。例如,下列程式會計算資料檔案中的項目數目
local count = 0 function Entry (b) count = count + 1 end dofile("data") print("number of entries: " .. count)下一個程式會在一個集合中收集檔案中找到的所有作者名稱,然後印出它們。(作者名稱是每個項目中的第一個欄位;因此,如果
b
是項目值,b[1]
就是作者。)
local authors = {} -- a set to collect authors function Entry (b) authors[b[1]] = true end dofile("data") for name in pairs(authors) do print(name) end請注意這些程式片段中的事件驅動方法:
Entry
函式作為回呼函式,會在 dofile
期間針對資料檔案中的每個項目呼叫。
如果檔案大小不是一大考量,我們可以使用名稱值對來表示
Entry{ author = "Donald E. Knuth", title = "Literate Programming", publisher = "CSLI", year = 1992 } Entry{ author = "Jon Bentley", title = "More Programming Pearls", publisher = "Addison-Wesley", year = 1990 }(如果這個格式讓您想起 BibTeX,這並非巧合。BibTeX 是 Lua 中建構函式語法的靈感來源之一。)這種格式就是我們所謂的自描述資料格式,因為每個資料都附有其意義的簡短描述。自描述資料比 CSV 或其他精簡符號更容易閱讀(至少對人類而言);必要時,它們很容易手動編輯;而且它們允許我們進行小修改,而無需變更資料檔案。例如,如果我們新增一個欄位,我們只需要在讀取程式中進行小幅變更,以便在欄位不存在時提供預設值。
使用名稱值格式後,我們收集作者的程式會變成
local authors = {} -- a set to collect authors function Entry (b) authors[b.author] = true end dofile("data") for name in pairs(authors) do print(name) end現在欄位的順序無關緊要。即使有些項目沒有作者,我們只需要變更
Entry
function Entry (b) if b.author then authors[b.author] = true end end
Lua 不僅執行速度快,編譯速度也快。例如,上面列出作者的程式在 2 MB 的資料中執行時間不到一秒鐘。同樣地,這並非偶然。資料描述一直是 Lua 自創建以來的主要應用程式之一,我們非常注意讓其編譯器對大型區塊執行得很快。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |