第一版是为 Lua 5.0 编写的。虽然在很大程度上仍适用于更高版本,但仍有一些不同之处。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目。
Lua 中的 编程 | ||
第一部分。语言 第 7 章。迭代器和通用 for |
这些先前迭代器的一个缺点是,我们需要为每个新循环创建一个新闭包。对于大多数情况而言,这不是一个真正的问题。例如,在 allwords
迭代器中,与读取整个文件相比,创建一个单个闭包的成本可以忽略不计。但是,在少数情况下,这种开销可能是不可取的。在这种情况下,我们可以使用通用 for 本身来保持迭代状态。
我们看到,通用 for 在循环期间在内部保留迭代器函数。实际上,它保留三个值:迭代器函数、不变状态和控制变量。现在让我们看看详细信息。
通用 for 的语法如下
for <var-list> in <exp-list> do <body> end其中
<var-list>
是一个或多个变量名称的列表,用逗号分隔,<exp-list>
是一个或多个表达式的列表,也用逗号分隔。通常,表达式列表只有一个元素,即对迭代器工厂的调用。例如,在代码中
for k, v in pairs(t) do print(k, v) end变量列表是
k, v
;表达式列表有一个元素 pairs(t)
。通常,变量列表也只有一个变量,如
for line in io.lines() do io.write(line, '\n') end我们称列表中的第一个变量为控制变量。在循环期间,它的值永远不会为 nil,因为当它变为 nil 时,循环结束。
for 做的第一件事是计算 in 之后的表达式。这些表达式应生成 for 保留的三个值:迭代器函数、不变状态和控制变量的初始值。就像在多重赋值中,列表的最后一个(或唯一一个)元素才能生成多个值;并且值的数量调整为三个,根据需要丢弃多余的值或添加 nil。(当我们使用简单的迭代器时,工厂仅返回迭代器函数,因此不变状态和控制变量获得 nil。)
在初始化步骤之后,for 使用两个参数调用迭代器函数:不变状态和控制变量。(请注意,对于 for 结构,不变状态没有任何意义。它仅从初始化步骤获取此值,并在调用迭代器函数时传递此值。)然后,for 将迭代器函数返回的值分配给其变量列表声明的变量。如果返回的第一个值(分配给控制变量的值)为 nil,则循环终止。否则,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因此,如果我们的迭代器函数为 f,不变状态为 s,控制变量的初始值为 a0,则控制变量将循环遍历值 a1 = f(s, a0)、a2 = f(s, a1) 等,直到 ai 为 nil。如果 for 有其他变量,它们只需获取
f
每次调用返回的多余值即可。
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |