1、迭代器與closure
在lua中,迭代器通常為函數,每調用一次函數,會返回集合中的下一個元素。每個迭代器在成功調用的時候,都需要保存一些狀態,closure(閉包)完美為迭代器運用而生。
t1 ={10, 20, 30}
it=values(t1) --創建閉包變量的參數為函數參數
while true do
local element=it() --調用閉包時的參數為匿名函數的參數
if(element==nil) then break
end
print(element)
end
t2={11,22,33}
for v in values(t2) do
print(v)
end
--輸出結果
--10
--20
--30
--11
--22
--33
從上面的例子可以看出,范型for相對于while給我們提供了更為清晰的實現邏輯。luo的內部函數已經為我們提供了迭代函數,運行foreach時我們會調用隱式的迭代器。
2、泛型for的語義
上面的迭代器有一個明顯的缺點,就是每次循環時都要創建一個新的closure變量,而不能運用之前已經創建好了的closure變量,如果我在這個循環外再加一個循環進行迭代時,這就成了一個很繁瑣并且容易出錯的問題。
下面出現的迭代器很好的解決了這個問題,就不必為每次的泛型for都創建一個新的closure變量了。
function ipairs(a)
return iter,a,0 --iter在這里只是一個函數變量,并不是調用函數
end
a={"one","two","three"}
for i,v in ipairs(a) do
print(i,v)
end
--上面的泛型for的寫法可以改為下面的while寫法
do
local _it,_s,_k=ipairs(a)
while true do
k,v=_it(_s,_k)
_k=k
if k==nil then break end
print(k,v)
end
end
--輸出結果
--1 one
--2 two
--3 three
--1 one
--2 two
--3 three
3、無狀態迭代器
function traverse(list)
return getnext,list,nil
end
list=nil
for line in io.lines() do
list={next=list, value=line}
end
for node in traverse(list) do
print(node.value)
end
--輸入
--a
--b
--c
--輸出
--c
--b
--a
通過上面的例子可以看出,可以無限次運用list變量和調用traverse函數而不必像第一種情況那樣每次循環之前都創建新的closure變量。
新聞熱點
疑難解答