無狀態迭代器,就是一種自身不保存任何狀態的迭代器,所以,咱們能夠在多個循環中使用同一個無狀態的迭代器,避免建立新的closure。node
在每次迭代中,for循環都會用恆定狀態和控制變量來調用迭代器函數。一個無狀態的迭代器能夠根據這兩個值來爲下次迭代生成下一個元素。典型例子:ipairs:迭代一個數組的全部元素。數組
a = {"one", "two", "three"} for i, v in inpairs(a) do print(i, v) end 迭代的狀態就是須要遍歷的table(一個恆定狀態,它不會在循環中改變)及當前的索引值(控制變量)。ipairs(工廠)和迭代器能夠在Lua中編寫出來。 local function iter (a, i) i = i + 1 local v = a[i] if v then return i, v end end function ipairs(a) return iter, a, 0 end 當Lua調用for循環中的ipairs(a)時,他會得到3個值:迭代器函數iter、恆定狀態a和控制變量的初值0.而後Lua調用iter(a,0),獲得1和a[1]。在第二次迭代中繼續調用iter(a,1),獲得2,a[2],一次類推,直至獲得第一個nil爲止。
函數pairs與ipairs相似,也是用於遍歷一個table中的全部元素。不一樣的是,它的迭代器函數是Lua中的一個基本函數next。函數
function pairs(t) return next, t, nil end 在調用next(t,k)時,k是table t的一個key。此調用會以table中的任意次序返回一組值:此table的下一個key及這個key所對應的值。而調用next(t, nil)時,返回table的第一組值。若沒有下一組值,next返回nil。 for k , v in next,t do <loop body> end
Lua中會自動將for循環中表達式列表的結果調整爲3個值。所以,上例中獲得了next、t和nil。oop
關於無狀態迭代器的另外一個例子(能夠遍歷列表的迭代器):lua
local function getnext( list , node) if not node then return list else return node.next end end function traverse (list) return getnext, list, nil end 這裏將鏈表的頭結點做爲恆定狀態(traverse返回的第二個值),而將當前節點做爲控制變量。第一次調用迭代器函數getnext時,node爲nil,所以函數返回list做爲第一個結點。在後續調用中node不在爲nil,此時迭代器會返回node.next. 對於此迭代器的使用: list = nil for line in io.lines() do list = {val = line, next = list} end for node in traverse(list) do print(node.val) end