Lua中的迭代器与泛型for|果冻想
本文是对于“果冻想”的《Lua入门系列》所作笔记,原文来自上面链接。
前言
function values( tb )
local i = 0
return function ( )
i = i + 1
return tb[i]
end
end
local testTb = {10, 20, 30}
for value in values(testTb) do
print(value)
end
泛型for的语义
泛型for在循环内保存了3个值:一个迭代器函数、一个恒定状态和一个控制变量。
泛型for的语法如下:
for <var-list> in <exp-list> do
<body>
end
<exp-list>是一个或多个表达式的列表,以逗号分隔。通常表达式列表只有一个元素,即一句对迭代器函数的调用。
for做的第一件事就是对in后面的表达式求值,这些表达式应该返回3个值供for保存:迭代器函数、恒定状态和控制变量的初值。
for var_1, ..., var_n in <explist> do <block> end -- 就等价于以下代码:
do
local _f, _s, _var = <explist> -- 返回迭代器函数、恒定状态和控制变量的初值
while true do
local var_1, ..., var_n = _f(_s, _var)
_var = var_1
if _var == nil then break end
<block>
end
end
end
无状态的迭代器
ipairs就是无状态迭代器的代表:
local aTb = {"one", "two", "three"}
for i, v in ipairs(aTb) do
print(i, v)
end
现在自己实现ipairs:
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end
function ipairs(a)
return iter, a, 0
end
函数pairs与ipairs类似,不同的是,它的迭代器函数是Lua中的一个基本函数next。
function pairs(a)
return next, t, nil
end
在调用next(t, k)时,k是table t的一个key。此调用会以table中的任意次序返回一组值:此table的下一个key,及这个key所对应的值。而调用next(t, nil)时,返回table的第一组值。若没有下一组值时,next返回nil。所以,我们也可以使用next来判断一个table是否为空。