迭代 - abbshr/Lua-newbie GitHub Wiki

迭代器

通过闭包生成迭代器:

function list_iter(t)
  local i = 0;
  local n = table.getn(t)
  return function () 
    i = i + 1
    if i <= n then return t[i] end
  end
end

泛型for使用迭代器:

for elem in list_iter(t) do
  print(elem)
end

泛型for在内部保存了三个值:迭代函数、状态常量、控制变量

Note:状态常量在for结构中没有用处,仅仅是在初始化迭代函数是提供参数

for <var-list> in <exp-list> do end
  • var-list的第一个变量:控制变量
  • exp-list:迭代工厂函数

执行过程:

  1. 初始化exp-list,返回结果会调整为3个,分别为泛型for需要的三个值,原则等同多值赋值
  2. 将状态常量与控制变量作为参数调用迭代函数
  3. 将迭代器返回的值赋给var-list
  4. 如果返回的第一个值为nil退出,否则回到第二步

等价于:

do
	local _iter, _state, _var = explist
	while true do
		local _var1, _var2, ... , _varn = iter(state, _var)
		_var = _var1
		if not _var then break end
	end
end	

无状态迭代器:不保留状态,无闭包开销

迭代的状态包括被遍历的表当前的索引下标

无状态迭代器将这两个值分别视为“状态常量”和“控制变量”,每次迭代都用这两个变量作为参数

ex:ipairs

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

多状态的迭代器

使用table来保存状态信息。不过这种方式的开销大于闭包创建,速度也略慢。

local function iter(state) end

function generator()
	local state = {state=..., var=...}
	return iter, state
end
⚠️ **GitHub.com Fallback** ⚠️