closure
就是一種能夠訪問其外部嵌套環境中的局部變量的函數closure
能夠記住它在一次遍歷中所在的位置closure
必須建立它的「非局部變量」一個closure
結構一般包含兩個函數函數
closure
自己closure
的工廠函數values
就是工廠,每次調用這個工廠,就會建立一個新的 closure
即迭代器其自己closure
將它的想要保存在其外部變量 t
和 i
中nil
,表示迭代的結束function values(t) local i = 0 return function () i = i + 1 return t[i] end end t = {123, 333, 444} iter = values(t) -- 建立迭代器 while true do local element = iter() -- 調用迭代器 if element == nil then break end print(element) end
for
記錄了每一次迭代循環iter
變量nil
時循環結束function values(t) local i = 0 return function () i = i + 1 return t[i] end end t = {123, 333, 444} -- 泛型 for t = {123, 333, 444} for element in values(t) do print(element) end
須要保持的值lua
string.find
在當前行中調用,以當前位置做爲起始位置來搜索一個單詞%w+
用來表示一個「單詞」, 英語匹配一個或多個文字或數字字符-- 編寫迭代器 function allwords() local line = io.read() -- 當前行 local pos = 1 -- 一行中的位置 return function () -- 迭代器函數 while line do -- 只要 line 不爲 nil 循環執行 -- 返回開始位置和結束位置 local start, end = string.find(line, "%w+", pos) if s then -- 是否找到一個單詞 pos = e + 1 -- 找到一個單詞,則移到這個單詞的下一個位置 return string.sub(line, s) -- 返回該單詞 else line = io.read() -- 這一行沒找到,嘗試讀取下一行 pos = 1 end end return nil -- 沒有剩餘行了,遍歷結束 end end -- 調用迭代器 for word in allwords() do print(word) end
closure
,開銷很大for
在循環過程內保存了迭代器函數保存了 3 個值code
-- var-list 變量列表 , exp-list 表達式列表, 多個元素可用 , 逗號分割 -- 一般表達式列表只有一個元素,即只有一句對迭代器工廠的調用 for <var-list> in <exp-list> do <code block> end for k, v in pairs(t) do print(k, v) end for line in io.lines() do io.write(line, "\n") end
nil
,當它爲 nil
時循環結束 for
首先會先對 in
後面的表達式求值,這些表達式應返回 3 個值供 for
保存element
nil
補足for
會以恆定狀態和控制變量來調用迭代器函數for
將迭代器函數的返回值賦予變量列表中的變量 nil
,則循環終止for
執行循環體,而後再次調用迭代器函數,並重復這個過程for
構建的角度來講,恆定狀態的內容與 for
自己是徹底無關的。for
只是保存了初始化中返回的值,並在調用迭代器函數時傳入該值。for var_1, ..., var_n in <exp-list> do <code clock> end -- 上述代碼等價於以下代碼s do -- _f 爲迭代器函數,_s 爲恆定狀態,控制變量的初值爲 a0 local _f, _s, _var = <exp-list> while true do local var_1, ... var_n = _f(_s, _var) _var = var_1 if _var == nil then break end end <code block> end
_f
爲迭代器函數,_s
爲恆定狀態,控制變量的初值爲 a₀
a₁ = f(s, a₀)
、a₂ = f(s, a₁)
以此類推ai
爲 nil
結束循環for
還有其餘變量,那麼 他們也會在每次調用 f
後得到額外的值