第一版是針對 Lua 5.0 編寫的。雖然對後續版本來說仍然有很大的關聯性,但還是有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您也可以協助 支持 Lua 專案。
![]() |
Lua 程式設計 | ![]() |
第一部分。語言 第 7 章。反覆運算器和一般 for |
反覆運算器通常需要保留比單一不變狀態和控制變數更多的狀態。最簡單的解決方案是使用封閉函數。另一種解決方案是將所有需要打包到表格中,並將此表格用作反覆運算的不變狀態。使用表格,反覆運算器可以在迴圈中保留所需的所有資料。此外,它可以在進行時變更資料。儘管狀態始終是相同的表格(因此是不變的),但表格內容會隨著迴圈而改變。由於此類反覆運算器在狀態中擁有所有資料,因此它們通常會捨棄一般 for 提供的第二個引數(反覆運算器變數)。
作為此技術的範例,我們將改寫反覆運算器 allwords
,它會遍歷目前輸入檔案中的所有字詞。這次,我們將使用具有兩個欄位(line
和 pos
)的表格來保留其狀態。
啟動反覆運算的函數很簡單。它必須傳回反覆運算器函數和初始狀態
local iterator -- to be defined later function allwords () local state = {line = io.read(), pos = 1} return iterator, state end
iterator
函數執行實際的工作
function iterator (state) while state.line do -- repeat while there are lines -- search for next word local s, e = string.find(state.line, "%w+", state.pos) if s then -- found a word? -- update next position (after this word) state.pos = e + 1 return string.sub(state.line, s, e) else -- word not found state.line = io.read() -- try next line... state.pos = 1 -- ... from first position end end return nil -- no more lines: end loop end
只要有可能,您都應該嘗試撰寫無狀態迭代器,這些迭代器會將其所有狀態保存在 for 變數中。使用這些迭代器時,您在開始迴圈時不會建立新的物件。如果您無法將您的迭代放入該模型中,那麼您應該嘗試使用閉包。除了比較優雅之外,閉包通常比使用表格的迭代器更有效率:首先,建立閉包比建立表格更便宜;其次,存取上層值比存取表格欄位更快。稍後我們將看到另一種撰寫迭代器的方法,使用 coroutine。這是功能最強大的解決方案,但稍微貴一點。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |