前言
迭代器就是一種可以遍歷一種集合中所有元素的機(jī)制,在Lua中,通常將迭代器表示為函數(shù)。每調(diào)用一次函數(shù),就返回集合中的“下一個”元素。每個迭代器都需要在每次成功調(diào)用之后保存一些狀態(tài),這樣才能知道它所在的位置及如何走到下一個位置,通過之前博文的總結(jié),閉包對于這樣的任務(wù)提供了極佳的支持?,F(xiàn)在我們就用代碼來實現(xiàn)一個簡單的迭代器。
這就是一個最簡單的迭代器,使用閉包來完成整個任務(wù);這只是一個簡單的例子,接下來,再看看泛型for的語義。
泛型for的語義
泛型for比較復(fù)雜,它在循環(huán)過程內(nèi)保存了迭代器函數(shù)。它實際上保存著3個值:一個迭代器函數(shù)、一個恒定狀態(tài)和一個控制變量。接下來,分別進(jìn)行總結(jié)。
泛型for的語法如下:
其中,var-list>是一個或多個變量名的列表,以逗號分隔;exp-list>是一個或多個表達(dá)式的列表,同樣以逗號分隔。通常表達(dá)式列表只有一個元素,即一句對迭代器函數(shù)的調(diào)用。例如:
for做的第一件事就是對in后面的表達(dá)式求值,這些表達(dá)式應(yīng)該返回3個值供for保存:迭代器函數(shù)、恒定狀態(tài)和控制變量的初值。這里和多重賦值是一樣的,只有最后一個表達(dá)式才會產(chǎn)生多個結(jié)果,并且只會保留前3個值,多余的值會被丟棄;而不夠的話,就以nil補(bǔ)足。
在初始化完成以后,for會以恒定狀態(tài)和控制變量來調(diào)用迭代器函數(shù)。然后for將迭代器函數(shù)的返回值賦予變量列表中的變量。如果第一個返回值為nil,那么循環(huán)就終止,否則,for執(zhí)行它的循環(huán)體,隨后再次調(diào)用迭代器函數(shù),并重復(fù)這個過程。在前言部分的代碼中,只是返回了迭代器函數(shù),并沒有返回恒定狀態(tài)和控制變量。下面通過代碼來說明這個問題,比如:
無狀態(tài)的迭代器
所謂“無狀態(tài)的迭代器”,就是一種自身不保存任何狀態(tài)的迭代器。因此,我們可以在多個循環(huán)中使用同一個無狀態(tài)的迭代器,避免創(chuàng)建新的閉包的開銷。
在每次迭代中,for循環(huán)都會用恒定狀態(tài)和控制變量來調(diào)用迭代器函數(shù)。一個無狀態(tài)的迭代器可以根據(jù)這兩個值來為下次迭代生成下一個元素。這類迭代器的代表就是ipairs。它可以用來迭代一個數(shù)組的所有元素。如下述演示代碼:
對于大家經(jīng)常迷惑的ipairs和pairs的區(qū)別,在這里就能看的一清二楚了,ipairs只能用于遍歷index是整型的table,同時,由于ipairs返回的控制變量初值為0,這就決定了,ipairs只能訪問index從1開始的key和value;ipairs不能返回nil,當(dāng)key對應(yīng)的值為nil時,就直接終止遍歷;而pairs則沒有要求。關(guān)于ipairs和pairs的具體差異,請參考這篇博文:點這里。
當(dāng)然了,有了無狀態(tài)的迭代器,就有了有狀態(tài)的迭代器了,有狀態(tài)的迭代器就是專門用一個table來保存狀態(tài);在無狀態(tài)的迭代器中,我們每一次都是迭代一個table,這個table就是一個無狀態(tài)的table,它不會再遍歷的過程中發(fā)生變化,而有狀態(tài)的迭代器,則會在遍歷的過程中對迭代的table進(jìn)行變更,迭代的table的狀態(tài)也隨之發(fā)生了變化。這里不做詳細(xì)的總結(jié)。
標(biāo)簽:黑龍江 新余 江西 武漢 延邊 嘉峪關(guān) 張掖 宜賓
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Lua中的迭代器和泛型for學(xué)習(xí)總結(jié)》,本文關(guān)鍵詞 Lua,中的,迭代,器,和,泛型,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。