所謂「迭代器」就是一種能夠遍歷一種集合中全部元素的機制。在Lua中,一般將迭代器表示爲函數。每調用一次函數,即返回集合中的「下一個」元素。
node
function values(t) local i = 0 return function() i = i + 1 return t[i] end end
在上例中,values就是一個工廠。每當調用這個工廠時,它就建立一個新的closure(即迭代器自己)。這closure 將它的狀態保存在其外部變量t 和i 中。每當調用這個迭代器時,它就從列表t 中返回下一個值。直到最後一個元素返回後,迭代器就會返回nil,以此表示迭代的結束。
數組
泛型for語法:app
for <var-list> in <exp-list> do <body> end
其中,<var-list>是一個或多個變量名的列表,以逗號分隔;<exp-list>是一個或多個表達式的列表,一樣以逗號分隔。一般表達式只有一個元素,即一句對迭代器工廠的調用。for 作的第一件事是對in 後面的表達式求值。函數
簡單示例:
lua
function values(t) local i = 0 return function() i = i + 1 return t[i] end end t = {1, 2, 3} for element in values(t) do print(element) end
「無狀態的迭代器」就是一種自身不保存任何狀態的迭代器。所以,咱們能夠在多個循環中使用同一個無狀態的迭代器,避免建立新的closure 開銷。
spa
在每次迭代中,for循環都會用恆定狀態和控制變量來調用迭代器函數。一個無狀態的迭代器能夠根據這兩個值來爲下次迭代生成下一個元素。這類迭代器的一個典型例子就是ipairs,它能夠用來迭代一個數組的全部元素:
指針
a = {"one", "two", "three"} for i, v in ipairs(a) do print(i, v) end
函數pairs 與ipairs 相似,也是用於遍歷一個table中的全部元素。不一樣的是,它的迭代函數是Lua中的一個基本函數next。
code
function pairs(t) return next, t, nil end
關於無狀態迭代器的另外一個有趣例子是一種能夠遍歷鏈表的迭代器:
orm
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
list = nil for line in io.lines() do list = {val = line, next = list} end for node in traverse(list) do print(node.val) end
文件操做:
對象
--讀取文件,顯示文件內容 local f = assert(io.open("test2.lua", 'r')) --至關於獲取流的指針或句柄或對象 --'r'讀取(read),'a'追加(append),'w'寫入(write),'b'以二進制形式打開(binary) local string = f:read("*all") --*all讀取全部,*line讀取一行,*number讀取一個數字,<num>讀取一個不超過<num>個數的字符 f:close() --關閉流 print(string)
--寫入文件 local f = assert(io.open("test2.txt", 'w')) f:write("welcome to lua \n I'm Jacedy") f:close()