天天看點

Lua:泛型for,疊代器,閉包實作ipairs(轉)

​​https://www.jb51.net/article/86840.htm​​

泛型for基本格式

for <var-list> in <exp-list> do 
 <body> 
end      

流程

  1. 首先,初始化,計算 in 後面表達式的值,表達式應該傳回 泛型for 需要的三個值:疊代函數、狀态常量、控制變量;與多值指派一樣,如果表達式傳回的結果個數不足三個會自動用nil 補足,多出部分會被忽略。
  2. 第二,将狀态常量和控制變量作為參數調用疊代函數(注意:對于 for 結構來說,狀态常量沒有用處,僅僅在初始化時擷取他的值并傳遞給疊代函數)
  3. 第三,将疊代函數傳回的值賦給變量清單。
  4. 第四,如果傳回的第一個值為 nil 循環結束,否則執行循環體。
  5. 第五,回到第二步再次調用疊代函數。

閉包實作ipairs

疊代器是一種可以周遊集合中所有元素的機制,在Lua中通常将疊代器表示為函數,每調用一次函數,就傳回集合中“下一個”元素,直到nil結束。

疊代器本身不會接着疊代,要while,for來控制疊代

function values(t)
 local i = 0
 return function() i = i + 1; return t[i] end
end

t = {10, 20, 30}

print("循環調用---------------")
iter = values(t)
while true do
 local el = iter()
 if el == nil then break end
 print(el)
end

print("泛型for調用---------------")
for el in values(t) do print(el) end

print("ipair實作原理---------------")
local function iter(s, i)
 i = i + 1
 local v = s[i]
 if v then return i, v end
end
function myipairs(s)
 return iter, s, 0
end

for i,v in myipairs(t) do
print(i)
print(v)
end      
  1. for第一次調用myipairs(t),生成了3個變量,疊代器iter,狀态常量s,控制變量0
  2. 在for的驅動下進行疊代,第一次傳入 iter(s,0),傳回值給到輸出清單i,v
  3. 閉包的作用下i是upvalue,下次傳入 iter(s,1)
  4. 持續第3步,傳出nil結束for循環

閉包性能問題