此第一版是針對 Lua 5.0 編寫的。雖然在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買此書,您同時也能支持 Lua 專案。
![]() |
程式設計 in Lua | ![]() |
第二部分。表格和物件 第 15 章。套件 |
正如我先前所述,使用表格來實作套件讓我們得以使用 Lua 的所有功能來操作它們。可能性是無限的。以下我僅提供一些建議。
我們不需要同時定義套件的所有公開項目。例如,我們可以在一個獨立的區塊中,將一個新項目新增到我們的 complex
套件
function complex.div (c1, c2) return complex.mul(c1, complex.inv(c2)) end(但請注意,私有部分僅限於一個檔案,我認為這是一件好事。) 相反地,我們可以在同一個檔案中定義多個套件。我們只需要將每個套件封裝在一個 do 區塊中,讓它的區域變數僅限於該區塊。
在套件外部,如果我們要經常使用某些操作,我們可以為它們提供區域名稱
local add, i = complex.add, complex.i c1 = add(complex.new(10, 20), i)或者,如果我們不想一直撰寫套件名稱,我們可以為套件本身提供一個較短的區域名稱
local C = complex c1 = C.add(C.new(10, 20), C.i)
撰寫一個函式來解開套件,將其所有名稱放入全域命名空間中,這很容易
function openpackage (ns) for n,v in pairs(ns) do _G[n] = v end end openpackage(complex) c1 = mul(new(10, 20), i)如果您在開啟套件時擔心名稱衝突,您可以在指派之前檢查名稱
function openpackage (ns) for n,v in pairs(ns) do if _G[n] ~= nil then error("name clash: " .. n .. " is already defined") end _G[n] = v end end
由於套件本身是表格,我們甚至可以巢狀套件;也就是說,我們可以在一個套件中建立另一個套件。然而,這種功能很少有必要。
另一個有趣的設施是自動載入,它只會在程式實際使用函式時載入函式。當我們載入一個自動載入套件時,它會建立一個空表格來表示套件,並設定表格的 __index
元方法來執行自動載入。然後,當我們呼叫任何尚未載入的函式時,會呼叫 __index
元方法來載入它。後續呼叫會發現函式已載入;因此,它們不會啟用元方法。
實作自動載入的一個簡單方法如下。每個函式都在一個輔助檔案中定義。(每個檔案中可以有多個函式。) 其中每個檔案都以標準方式定義其函式,例如像這裡
function pack1.foo () ... end function pack1.goo () ... end然而,檔案不會建立套件,因為在載入函式時套件已存在。
在主套件中,我們定義一個輔助表格,用來描述我們可以在哪裡找到每個函式
local location = { foo = "/usr/local/lua/lib/pack1_1.lua", goo = "/usr/local/lua/lib/pack1_1.lua", foo1 = "/usr/local/lua/lib/pack1_2.lua", goo1 = "/usr/local/lua/lib/pack1_3.lua", }然後我們建立套件並定義其元方法
pack1 = {} setmetatable(pack1, {__index = function (t, funcname) local file = location[funcname] if not file then error("package pack1 does not define " .. funcname) end assert(loadfile(file))() -- load and run definition return t[funcname] -- return the function end}) return pack1載入這個套件後,程式第一次執行
pack1.foo()
時,它會呼叫 __index
元方法,這很簡單。它會檢查函式是否有對應的檔案,並載入該檔案。唯一需要注意的是,它不僅必須載入檔案,還必須將函式作為存取的結果傳回。
由於整個系統都是用 Lua 撰寫的,因此很容易改變其行為。例如,函式可以用 C 定義,元方法使用 loadlib
載入它們。或者我們可以在全域表格中設定一個元方法,以自動載入整個套件。可能性是無窮無盡的。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |