第一版针对 Lua 5.0 编写。虽然在很大程度上仍然适用于后续版本,但存在一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目


7.3 – 无状态迭代器

顾名思义,无状态迭代器是不自行保留任何状态的迭代器。因此,我们可以在多个循环中使用同一个无状态迭代器,避免创建新闭包的成本。

在每次迭代中,for 循环使用两个参数调用其迭代器函数:不变状态和控制变量。无状态迭代器仅使用这两个参数为迭代生成下一个元素。这种迭代器的典型示例是 ipairs,它遍历数组中的所有元素,如下所示

    a = {"one", "two", "three"}
    for i, v in ipairs(a) do
      print(i, v)
    end
迭代状态是正在遍历的表(不变状态,在循环期间不会更改),加上当前索引(控制变量)。ipairs 和它返回的迭代器都非常简单;我们可以用 Lua 编写如下内容
    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
当 Lua 在 for 循环中调用 ipairs(a) 时,它会获取三个值:iter 函数作为迭代器,a 作为不变状态,以及零作为控制变量的初始值。然后,Lua 调用 iter(a, 0),结果为 1, a[1](除非 a[1] 已经是 nil)。在第二次迭代中,它调用 iter(a, 1),结果为 2, a[2],依此类推,直到第一个 nil 元素。

pairs 函数遍历表中的所有元素,类似,但迭代器函数是 next 函数,这是 Lua 中的一个基本函数

    function pairs (t)
      return next, t, nil
    end
调用 next(t, k),其中 k 是表 t 的键,将按任意顺序返回表中的下一个键。(它还将与该键关联的值作为第二个返回值返回。)调用 next(t, nil) 将返回第一个对。如果没有更多对,next 将返回 nil

有些人更喜欢直接使用 next,而不调用 pairs

    for k, v in next, t do
      ...
    end
请记住,for 循环的表达式列表已调整为三个结果,因此 Lua 获取 nexttnil,这正是它调用 pairs(t) 时获取的内容。