吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1280|回复: 2
收起左侧

[其他转载] lua学习之迭代器与泛型 for 第三篇

[复制链接]
看看天空 发表于 2020-3-2 23:06

迭代器与泛型 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. 生成器允许两个或多个并行的迭代过程
    1. 逐个单词的比对两个文件,需同时遍历两个文件
  2. 且可在迭代体中使用 breakreturn 语句

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

E式丶男孩 发表于 2020-3-3 00:20
硬核教程啊
头像被屏蔽
那年听风 发表于 2020-3-3 01:45
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 00:39

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表