第一版是為 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但有一些不同。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您還可以幫助 支持 Lua 項目。
![]() |
用 Lua 編程 | ![]() |
第二部分。表和物件 第 17 章。弱表 |
一種常見的編程技術是用空間換取時間。您可以通過記憶化函數結果來加速某些函數,以便以後使用相同參數呼叫函數時,它可以重複使用結果。
想像一個通用伺服器,它接收包含 Lua 程式碼字串的請求。每次收到請求時,它都會對字串執行 loadstring
,然後呼叫結果函數。但是,loadstring
是一個昂貴的函數,而對伺服器的某些命令可能非常頻繁。伺服器可以記憶化 loadstring
的結果,使用輔助表,而不是在每次收到 "closeconnection()"
之類的通用命令時重複呼叫 loadstring
。在呼叫 loadstring
之前,伺服器會在表中檢查該字串是否已經有轉換。如果找不到字串,則(且僅當)伺服器呼叫 loadstring
並將結果儲存在表中。我們可以將此行為封裝到一個新函數中
local results = {} function mem_loadstring (s) if results[s] then -- result available? return results[s] -- reuse it else local res = loadstring(s) -- compute new result results[s] = res -- save for later reuse return res end end
此方案可以節省大量的空間。不過,它也可能造成意想不到的浪費。雖然有些命令會重複執行,但許多其他命令只會執行一次。隨著時間的推移,表格 results
會累積伺服器曾經接收過的所有命令及其各自的代碼;經過一段時間後,這將耗盡伺服器的記憶體。一個弱表格提供了一個簡單的解決方案來解決此問題。如果 results
表格具有弱值,每個垃圾回收週期都會移除在當時未使用的所有轉譯(這表示幾乎所有轉譯都會被移除)
local results = {} setmetatable(results, {__mode = "v"}) -- make values weak function mem_loadstring (s) ... -- as before實際上,由於索引始終為字串,如果需要,我們可以讓該表格完全變弱
setmetatable(results, {__mode = "kv"})最終結果完全相同。
memoize 技術也可以用來確保某種物件的唯一性。例如,假設一個系統將顏色表示為表格,其中包含某些範圍內的欄位 red
、green
和 blue
。一個天真的顏色工廠會為每個新要求產生一個新顏色
function createRGB (r, g, b) return {red = r, green = g, blue = b} end使用 memoize 技術,我們可以為相同的顏色重複使用相同的表格。若要為每個顏色建立一個唯一的金鑰,我們只需將顏色索引與中間的分隔符號串接起來
local results = {} setmetatable(results, {__mode = "v"}) -- make values weak function createRGB (r, g, b) local key = r .. "-" .. g .. "-" .. b if results[key] then return results[key] else local newcolor = {red = r, green = g, blue = b} results[key] = newcolor return newcolor end end此實作的一個有趣結果是,使用者可以使用原始相等運算子來比較顏色,因為兩個共存的相等顏色總是會由相同的表格表示。請注意,相同的顏色可能會在不同的時間由不同的表格表示,因為垃圾回收器週期會不時清除
results
表格。不過,只要給定的顏色正在使用中,它就不會從 results
中移除。因此,只要一個顏色存活的時間夠長,可以與新的顏色進行比較,其表示也會存活的時間夠長,可以被新的顏色重複使用。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |