迭代器是用于遍歷集合或容器中元素的一種結(jié)構(gòu)。在 Lua 語言中,集合往往指的是可以用來創(chuàng)建各種數(shù)據(jù)結(jié)構(gòu)的表。比如,數(shù)組就是用表來創(chuàng)建的。
通用迭代器可以訪問集合中的鍵值對。下面是通用迭代器的一個簡單例子:
array = {"Lua", "Tutorial"}
for key,value in ipairs(array)
do
print(key, value)
end
執(zhí)行的上面的代碼,我們可以得到如下的輸出結(jié)果:
1 Lua
2 Tutorial
上面的例子中使用了 Lua 提供的默認(rèn)迭代器函數(shù) ipairs。
在 Lua 語言中,我們使用函數(shù)表示迭代器。根據(jù)是否在迭代器函數(shù)中是否維護(hù)狀態(tài)信息,我們將迭代器分為以下兩類:
由此迭代器的名稱就可以看出來,這一類的迭代器函數(shù)中不會保存任何中間狀態(tài)。
讓我們一起來看一下下面這個例子。在這個例子中,我們用一個簡單的函數(shù)創(chuàng)建了一個自己的迭代器。這個迭代器用以輸出 n 個數(shù)的平方值。
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
for i,n in square,3,0
do
print(i,n)
end
執(zhí)行上面的代碼,我們可以得到如下的輸出結(jié)果:
1 1
2 4
3 9
我們可以稍微的修改一下上面的代碼,使得此迭代器可以像 ipairs 那樣工作。如下所示:
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0
end
for i,n in squares(3)
do
print(i,n)
end
執(zhí)行上面的代碼,我們可以得到如下的輸出結(jié)果:
1 1
2 4
3 9
前面的例子使用的迭代器函數(shù)是不保存狀態(tài)的。每次調(diào)用迭代器函數(shù)時,函數(shù)基于傳入函數(shù)的第二個變量訪問集合的下一個元素。在 Lua 中可以使用閉包來存儲當(dāng)前元素的狀態(tài)。閉包通過函數(shù)調(diào)用得到變量的值。為了創(chuàng)建一個新的閉包,我們需創(chuàng)建兩個函數(shù),包括閉包函數(shù)本身和一個工廠函數(shù),其中工廠函數(shù)用于創(chuàng)建閉包。
下面的示例中,我們將使用閉包來創(chuàng)建我們的迭代器。
array = {"Lua", "Tutorial"}
function elementIterator (collection)
local index = 0
local count = #collection
-- 返回閉包函數(shù)
return function ()
index = index + 1
if index <= count
then
-- 返回迭代器的當(dāng)前元素
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
執(zhí)行上面的代碼,我們可以得到如下的輸出結(jié)果:
Lua
Tutorial
上面的例子中我們可以看到,在 elementIterator 函數(shù)內(nèi)定義了另外一個匿名函數(shù)。此匿名函數(shù)中使用了一個外部變量 index (譯注:此變量在匿名函數(shù)之外,elementIterator 函數(shù)內(nèi))。每次內(nèi)部的匿名函數(shù)被調(diào)用時,都會將 index 的值增加 1,并統(tǒng)計數(shù)返回的每個元素。
我們可以參照上面的方法使用閉包創(chuàng)建一個迭代器函數(shù)。每次我們使用迭代器遍歷集合時,它都可以返回多個元素。