迭代器和闭包
迭代器是—种可以让我们遍历一个集合中所有元素的代码结构。
闭包就是一个可以访问其自身的环境中一个或多个局部变量的函数。
一个闭包结构通常涉及两个函数:闭包本身和一个用于创建该闭包及其封装变量的工厂
例,一个简单的迭代器
function values(t)
local i = 0
return function()
i = i + 1
return t[i]
end
end
values
就是工厂,这个闭包将它的状态保存在其外部的变量t和i中,这两个变量也是由values
创建的。每次调用这个迭代器时,它就从列表t中返回下一个值。在遍历完最后一个元素后,迭代器返回nil,表示迭代结束。
t = {10, 20, 30}
iter = values(t) --创建迭代器
while true do
local element = iter() --调用迭代器
if element == nil then break end
print(element)
end
使用泛型for更简单
t = {10,20,30}
for element in values(t) do
print(element)
end
泛型for的语法
在循环过程中在其内部保存了迭代函数
泛型for保存了三个值:一个迭代函数、一个不可变状态和一个控制变量。
语法
for var-list in exp-list do
body
end
常见的如:
for v in ipars(t) do
print(k, v)
end
无状态迭代器
一种自身不保存任何状态的迭代器
因此,可以在多个循环中使用同一个无状态迭代器,从而避免创建新闭包的开销。
如:for .. in .. ipars() do .. end
a = {"one", "two", "there"}
for i, v in ipairs(a) do
print(i, v)
end
--ipairs迭代器实现
local function iter (t, i)
i = i + 1
local v = t[i]
if v then
return i, v
end
end
function ipairs (t)
return iter, t, 0 --返回三个值:即迭代函数iter、不可变状态表t和控制变量的初始值0。
end
--pairs也是一样
function pairs (t)
return next, t, nil
end
在调用
next(t,k)
时,k是表t的一个键,该函数会以随机次序返回表中的下一个键及k对应的值(作为第二个返回值)。调用next(t, nil)
时,返回表中的第一个键值对。当所有元素被遍历完时,函数next
返回nil
。
迭代器接收一个函数作为参数,这个函数在循环的内部被调用,这种迭代器就被称为真正的迭代器。