第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些差异。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目。
用 Lua 编程 | ||
第一部分。语言 第 7 章。迭代器和通用 for |
“迭代器”这个名称有点误导,因为我们的迭代器不会迭代:迭代的是 for 循环。迭代器只为迭代提供连续的值。也许一个更好的名称是“生成器”,但“迭代器”已经在其他语言中得到广泛使用,例如 Java。
然而,还有另一种构建迭代器的方法,其中迭代器实际上执行迭代。当我们使用此类迭代器时,我们不会编写循环;相反,我们只需使用一个参数调用迭代器,该参数描述了迭代器在每次迭代中必须执行的操作。更具体地说,迭代器接收一个函数作为参数,并在其循环中调用该函数。
作为一个具体的示例,让我们使用这种样式再次重写 allwords
迭代器
function allwords (f) -- repeat for each line in the file for l in io.lines() do -- repeat for each word in the line for w in string.gfind(l, "%w+") do -- call the function f(w) end end end要使用此类迭代器,我们必须提供循环体作为函数。如果我们只想打印每个单词,我们只需使用
print
allwords(print)更常见的是,我们使用匿名函数作为主体。例如,下一个代码片段统计输入文件中单词“hello”出现的次数
local count = 0 allwords(function (w) if w == "hello" then count = count + 1 end end) print(count)使用先前的迭代器样式编写的相同任务并没有太大的不同
local count = 0 for w in allwords() do if w == "hello" then count = count + 1 end end print(count)
真正的迭代器在 Lua 的旧版本中很流行,当时该语言没有 for 语句。它们与生成器样式迭代器相比如何?两种样式的开销大致相同:每次迭代一个函数调用。一方面,使用第二种样式编写迭代器更容易(尽管我们可以通过协程恢复这种容易性)。另一方面,生成器样式更灵活。首先,它允许两个或更多并行迭代。(例如,考虑按单词比较两个文件时遇到的迭代问题。)其次,它允许在迭代器主体中使用 break 和 return。(使用真正的迭代器,return 从匿名函数返回,而不是从执行迭代的函数返回。)
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |