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

迭代器与泛型 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 语句

本篇文章由一文多发平台ArtiPub自动发布

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容