和c++類似,lua也有迭代器,如汎型for。泛型for需要三個值:迭代函式、狀態常量、控制變數
乙個典型的泛型for如下:
for k, v in pairs(t) do
print(k, v)
end
泛型for的執行過程:
首先,初始化,計算 in 後面表示式的值,表示式應該返回泛型for需要的三個值:迭代函式、狀態常量、控制變數。(並不保證一定會返回三個值,有時只會傳遞迭代函式,其他值就為nil)
第二,將狀態常量和控制變數作為引數呼叫迭代函式(對於for結構來說,狀態常量並沒有用到,僅僅在初始化時獲取它的值並傳遞給迭代函式)。
第三,將迭代函式返回的值賦給for的變數列表。
第四,如果返回的第乙個值為nil,則迴圈結束,否則執行迴圈體。
第五,回到第二步再次呼叫迭代函式
無狀態的迭代器:
無狀態的迭代器是指不保留任何狀態的迭代器,因此在迴圈中我們可以利用無狀態迭代器避免建立閉包花費額外的代價。每一次迭代,迭代函式都是用兩個變數(狀態常量和控制變數)的值作為引數被呼叫,乙個無狀態的迭代器只利用這兩個值可以獲取下乙個元素。這種無狀態迭代器的典型的簡單的例子是ipairs,他遍歷陣列的每乙個元素。
乙個簡易的無狀態迭代器實現如下:
function iter (a, i)
print("iter")
i = i + 1
if a[i] then
local v = a[i] ^ 2
return i, v
endend
function ipairs (a)
print("ipairs")
return iter, a, 0
endlocal tab =
for k, v in ipairs(tab) do
print(k, v)
end
執行結果如下:
ipairs
iter
1 1.0
iter
2 4.0
iter
可以發現 ipairs 函式只執行了一次,iter函式執行多次。至於
iter, a, 0
就是返回的迭代函式、狀態常量以及控制變數三個引數。
在以上的寫法中,lua呼叫ipairs(a)開始迴圈,它先獲取三個值:迭代函式 iter、狀態常量 a、控制變數初始值 0,然後 lua呼叫 iter(a,0) 返回1, a[1](除非a[1]=nil),第二次迭代呼叫iter(a,1)返回2,a[2]……直到第乙個nil元素,此時 iter 不會呼叫 return 函式,for語句中 k, v 的值就都會是 nil,隨即 for 語句結束。
這裡有乙個疑問,為什麼第二次會呼叫 iter(a, 1),第三次 iter(a, 2)?還望指教
貌似是通過 iter 函式第乙個返回值進行控制變數的迭代。
多狀態的迭代器:
很多情況下,迭代器需要儲存多個狀態資訊而不是簡單的狀態常量和控制變數,最簡單的方法是使用閉包,還有一種方法就是將所有的狀態資訊封裝到table內,將table作為迭代器的狀態常量,因為這種情況下可以將所有的資訊存放在table內,所以迭代函式通常不需要第二個引數。
乙個簡易的多狀態迭代器實現如下:
local tab =
function iter2 (a)
local index = 0
local len = #a
-- 閉包函式
return function()
index = index + 1
if a[index] then
return index, a[index] ^ 2
endend
endfor k, v in iter2(tab) do
print(k, v)
end
輸出:
1 1.0
2 4.0
可以發現相比無狀態迭代器,多狀態迭代器使用了閉包,也即使用了內嵌函式,並將控制變數變成乙個upvalue。
lua迭代器原理
當lua呼叫for迴圈中的ipairs a 時,它會獲得三個值 迭代器函式iter 恆定狀態a和控制變數的處置0。然後lua呼叫iter a,0 得到1,a 1 在第二次迭代中,繼續呼叫iter a,1 得到2,a 2 依次類推,直到得到的第乙個nil元素為止。pairs與ipairs類似,也是用於...
Lua基礎 迭代器
官方的文件說 迭代器 iterator 是一種物件,它能夠用來遍歷標準模板庫容器中的部分或全部元素,每個迭代器物件代表容器中的確定的位址 在lua中迭代器是一種支援指標型別的結構,它可以遍歷集合的每乙個元素。迭代器的種類主要有 泛型for迭代器 無狀態的迭代器 多狀態的迭代器 下面看幾個例子 ipa...
Lua程式設計 迭代器
迭代器 一種可以遍歷乙個集合中所有元素的 結構 函式表述迭代器 每一次呼叫 函式就會返回集合的下乙個元素 所有迭代器都需要在連續呼叫之間儲存一些狀態 知道當前所處位置以及如何從當前位置到下一步位置 自定義迭代器 閉包為儲存狀態提供了一種良好的機制 閉包就是乙個可以訪問其自身環境中乙個或者多個區域性變...