您的位置:首页 > 编程语言 > Lua

lua学习之迭代器与泛型 for 第三篇

2020-03-02 23:09 225 查看

迭代器与泛型 for 3

具有复杂状态的迭代器

  1. 使用 closure 可以保存迭代器所需保存的所有状态
  2. 也可以将迭代器所需的所有状态打包为一个 table 并保存在 恒定状态中
  3. 在循环过程中 恒定状态 总是同一个 table
  4. 但这个 table 的内容却可以改变即在循环过程中改变 table 数据
  5. 由于这种迭代器可以保存所有数据将其存储到 恒定状态中,因此第二个参数 控制变量 可以忽略
local iterator
function allwords()
local state = {line = io.read(), pos = 1}
return iterator, state
end

function iterator(state)
while state.line do -- 若为有效行的内容就进入循环
-- 搜索下一个单词
local s, e = string.find(state.line, "%w+", state.pos)
if s then -- 找到一个单词
state.pos = e + 1
return string.sub(state.line, s, e)
else -- 没有找到单词
state.line = io.read() -- 尝试读取下一行
state.pos = 1
end
end
return nil
end

错误记录

  1. 这里编码时犯了一个错误,没找到单词时使用的是函数定义 io.read ,而不是函数调用 io.read()
  2. 所以会报错 bad argument #1 to 'find' (string expected, got function)
  3. 意为第一个参数期望获得 string 类型,实际上得到的确实 function 类型
  4. 因为输入的第一行肯定会有单词,所以不会进入 else 读取下一行
  5. 而打印出第一行的所有单词后,就不会尝试读取输入了,因为 string.find(state.line, ...) 其中的 第一个参数已经为 function 类型了,所以循环结束
  6. io.read() 用户输入任何东西都会为 string 类型
  7. 除非指定输入 io.read("*number") 这样就指定用户输入为 number 类型了

与无状态迭代器的对比

  1. 无状态迭代器将所有状态保存在 for 变量中
  2. 无需再开始一个循环时创建任何对象
  3. 基于 closure 实现的 table 比一个使用 table 的迭代器高效
  4. 因为访问 「非局部变量」要比访问 table

真正的迭代器

  1. 迭代器没有做实际的迭代,真正做迭代的是 for 循环
  2. 迭代器只是为每次迭代提供成功后的返回值
  3. 准确地称呼应为「生成器」

在迭代器中做实际的迭代操作

  1. 无需写循环
  2. 需要描述每次迭代时所需执行的动作或行为的参数,即参数为某个函数
  3. 迭代器接受一个函数作为参数,并在其内部循环中调用这个函数
function allwords(f)
for line in io.read() do
-- gmatch 匹配所有符合模式的字符串
for word in string.gmatch(line, "%w+") do
f(word)
end
end
end

allwords(print)
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)

迭代器与生成器的对比

相同点

  1. 开销一致
  2. 每次迭代都有一次函数调用

不同点

迭代器

  1. return 语句只能从匿名函数中返回
  2. 不能从做迭代的函数中返回

生成器

  1. 生成器允许两个或多个并行的迭代过程 逐个单词的比对两个文件,需同时遍历两个文件
  • 且可在迭代体中使用 breakreturn 语句

  • 本篇文章由一文多发平台ArtiPub自动发布 (window.slotbydup = window.slotbydup || []).push({ id: "u5894387", container: "_0hv0l6ey3zro", async: true });
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: