第55页 迭代器与泛型 for
松鼠亲自奥利奥 (mastodon:@tonyseek@douban.city)
读过 LUA程序设计(第2版)
- 章节名:迭代器与泛型 for
- 页码:第55页
## 简单迭代器协议 Lua 中的简单迭代器协议就是“调用函数”,调用一个函数,它的返回值为本次迭代得到的对象。 既然同一个函数可以每次调用产生不同的返回值,那么函数的“状态”来自闭包时绑定的 upvalue。 <代码开始 lang=" javascript"> for element in myiter() do do_something(element) end </代码结束> 等价于 <代码开始 lang=" javascript"> local _iter = myiter() while true do local element = _iter() if element == nil then break end do_something(element) end </代码结束> ## 泛型 for 语义 for 在迭代过程保留的三个值:迭代器函数,恒定状态,控制变量 <代码开始 lang=" javascript"> for var1, var2, var3 in myiter() do do_something(var1, var2, var3) end </代码结束> 等价于: <代码开始 lang=" lua"> local iter_func, state, control_var = myiter() -- 这就是那三个值了,不足补nil while true do local var1, var2, var3 = iter_func(state, control_var) -- 恒定状态还是同一个 control_var = var1 -- 每次迭代过后,返回值的第一个成为新任控制变量 if control_var == nil then break -- 控制变量为 nil 则迭代结束 end do_something(var1, var2, var3) -- 循环体 end </代码结束> 通过 for 语义可以编写不依赖闭包保存状态的迭代器,例如遍历列表的 ipairs: <代码开始 lang=" lua">
恒定状态为被迭代的列表,始终不变;控制变量为下一个元素的索引,每次迭代都被更新。 ## 有复杂状态的迭代器 用泛型 for 语义编写的迭代器也可以不借助闭包就拥有复杂状态的迭代器,因为恒定状态虽然只能指向同一个对象,但这个对象的内容并非不可改变。可以自己构造一个 table,保持原恒定状态对象的同时记录状态的转移。 ## 用回调函数做迭代器 和 ruby 的做法一样,使用匿名函数回调来做迭代器(内部迭代器),曾经在 Lua 没有 for 语法的时候被使用,但是作者不建议现在还这么用,原因两点: * 每次迭代都要调用一次函数 * 不能用 break/return 中止迭代
松鼠亲自奥利奥对本书的所有笔记 · · · · · ·
-
第36页 函数
== 泛型传参 == Lua 在变量问题上比 Python 宽容很多,比如未定义变量在 Python 中被访问是一...
-
第55页 迭代器与泛型 for
-
第66页 编译、执行与错误
== 运行时编译 == * loadstring(codestring),返回一个签名为 function(...) 的正规函数 * lo...
-
第85页 协同程序(Coroutine)
一个协程有四种状态:suspended、running、dead、normal。 coroutine.create 传入一个无参数...
说明 · · · · · ·
表示其中内容是对原文的摘抄