Lua中的迭代器和泛型for介紹
任何一種結(jié)構(gòu),只要允許你遍歷集合中所有元素的都可稱之為迭代器。lua中常常使用函數(shù)來(lái)描述迭代器,每次調(diào)用該函數(shù)都返回集合的下一個(gè)元素。每一個(gè)迭代器都需要保存一些狀態(tài)來(lái)知道當(dāng)前處于什么位置和如何進(jìn)行下一次迭代。對(duì)于這樣的任務(wù),閉包提供了很好的機(jī)制來(lái)完成。一個(gè)典型的閉包結(jié)構(gòu)包含兩個(gè)函數(shù):一個(gè)是閉包自身,一個(gè)是創(chuàng)建閉包的工廠。
例如,我們可以寫過(guò)簡(jiǎn)單的list迭代器,讓他僅僅返回值。
function values( t )
local i = 0;
return function() i = i + 1;return t[i] end
end
tb = {33, 44, 55}
for v in values(tb) do
print(v)
end
泛型for簿記所有迭代循環(huán),首先調(diào)用迭代工廠,并內(nèi)部保存迭代函數(shù)。每次迭代時(shí)調(diào)用新的迭代函數(shù)。但迭代器返回nil循環(huán)結(jié)束。
上面的迭代器有個(gè)瑕疵:需要?jiǎng)?chuàng)建一個(gè)閉包。創(chuàng)建閉包是需要代價(jià)的,只是大部分情況下都沒(méi)問(wèn)題,然而有些情況卻是不能容忍這個(gè)代價(jià)的。這時(shí)的解決方法是使用泛型for。泛型for本身保存迭代狀態(tài),包括迭代函數(shù),狀態(tài)常量,控制變量,因此不必付出閉包的代價(jià),稱這種迭代器為無(wú)狀態(tài)迭代器。
泛型for的語(yǔ)法:
for <var-list> in <exp-list> do
<body>
end
執(zhí)行過(guò)程:
1.初始化迭代函數(shù),狀態(tài)常量,控制變量,不足補(bǔ)nil,多出忽略。
2.狀態(tài)常量,控制變量作為參數(shù)調(diào)用迭代函數(shù)。
3.將迭代函數(shù)返回的值付給變量列表。
4.如果返回的第一個(gè)值為nil,則循環(huán)結(jié)束,否則執(zhí)行循環(huán)體。
5.回到第2步。
如果遇到需要保存多個(gè)狀態(tài),還有種方法是將所有狀態(tài)封裝到表中。實(shí)際上,我們不推薦這么寫。因?yàn)閯?chuàng)建閉包的代價(jià)比創(chuàng)建表的要小,而且lua處理閉包的速度更快些。還有更強(qiáng)大更復(fù)雜的方式是使用協(xié)同來(lái)創(chuàng)建迭代器。
相關(guān)文章
Lua協(xié)同程序(COROUTINE)運(yùn)行步驟分解
這篇文章主要介紹了Lua協(xié)同程序(COROUTINE)運(yùn)行步驟分解,本文著重分解協(xié)同程序的運(yùn)行步驟,需要的朋友可以參考下2015-01-01Ruby元編程技術(shù)詳解(Ruby Metaprogramming techniques)
這篇文章主要介紹了Ruby元編程技術(shù)詳解(Ruby Metaprogramming techniques),本文講解了11個(gè)關(guān)于元編程的技術(shù)和技巧,需要的朋友可以參考下2015-04-04簡(jiǎn)單的Lua 連接操作mysql數(shù)據(jù)庫(kù)的方法
lua連接數(shù)據(jù)庫(kù)不只luasql這個(gè)庫(kù),但目前更新最快的的貌似是這個(gè)luasql,他是開源的,下面我們就來(lái)看看如何來(lái)具體操作吧2015-10-10Lua中調(diào)用函數(shù)使用點(diǎn)號(hào)和冒號(hào)的區(qū)別
這篇文章主要介紹了Lua中調(diào)用函數(shù)使用點(diǎn)號(hào)和冒號(hào)的區(qū)別,本文涉及了Lua中面向?qū)ο蟮囊恍┑闹R(shí),并給出了一個(gè)簡(jiǎn)單的類代碼實(shí)例,需要的朋友可以參考下2014-09-09