1. 所謂"迭代器",就是一種可以遍歷某個集合中所有元素的機制,在lua中迭代器通常表示爲函數,而具體的實現有很多種。
整個迭代的過程基本如下:
首先是通過迭代器工廠創建迭代器;
然後每次調用這個迭代器時,它就會從指定的集合中返回下一個元素;
直到最後一個元素返回後,迭代器就會返回nil,以此表示迭代結束。
2. 閉包是一種最典型的迭代器函數,因爲閉包中的"非局部的變量"可以用來在每次調用之間保持一些狀態,從而使閉包可以記住每次迭代所在的位置。
3. lua中的泛型for天然就是爲迭代而設計的,其語法格式如下:
for <var-list> in <exp-list> do
<body>
end
備註:<var-list>是變量名列表,用來存儲迭代器函數的返回值,其中的第一個變量固定稱爲"控制變量",當它爲nil時迭代結束;
<exp-list>是表達式列表,通常只有一個,即對迭代器工廠的調用。
泛型for的執行流程如下:
[1]. 對關鍵字"in"後面的表達式求值,該表達式通常會返回3個值供for保存,迭代器函數、恆定狀態、控制變量的初值
[2]. 將恆定狀態(比如要遍歷的table)和控制變量作爲實參,調用迭代器函數
[3]. 將迭代器函數的返回值賦給變量列表,如果控制變量爲nil,則迭代結束
[4]. 如果控制變量是有效值,則執行循環體,隨後再次調用迭代器函數,執行下一次迭代
4. 泛型for中的迭代器函數可以是一種自身不保存任何狀態的普通函數,又叫做"無狀態迭代器",每次迭代都是根據恆定狀態和控制變量來遍歷每個元素。
這種"無狀態迭代器"的優點顯而易見,它將狀態保存在泛型for中,不需要創建任何新的對象,所以儘可能嘗試編寫這種迭代器。
5. 泛型for中的迭代器函數也可以是閉包,這通常意味着迭代器需要保存很多狀態,而泛型for只提供了一個恆定狀態和一個控制變量用於狀態的保存,使用閉包可以優雅的解決這個問題。
6. 有複雜狀態的迭代器除了可以通過閉包實現,還可以將這些複雜狀態全部打包爲一個table,保存在恆定狀態中,這也意味着迭代器不再需要泛型for提供的控制變量了。