closure
就是一种能够访问其外部嵌套环境中的局部变量的函数closure
能够记住它在一次遍历中所在的位置closure
必须建立它的「非局部变量」一个closure
结构一般包含两个函数函数
closure
自己closure
的工厂函数values
就是工厂,每次调用这个工厂,就会建立一个新的 closure
即迭代器其自己closure
将它的想要保存在其外部变量 t
和 i
中nil
,表示迭代的结束function values(t) local i = 0 return function () i = i + 1 return t[i] end end t = {123, 333, 444} iter = values(t) -- 建立迭代器 while true do local element = iter() -- 调用迭代器 if element == nil then break end print(element) end
for
记录了每一次迭代循环iter
变量nil
时循环结束function values(t) local i = 0 return function () i = i + 1 return t[i] end end t = {123, 333, 444} -- 泛型 for t = {123, 333, 444} for element in values(t) do print(element) end
须要保持的值lua
string.find
在当前行中调用,以当前位置做为起始位置来搜索一个单词%w+
用来表示一个「单词」, 英语匹配一个或多个文字或数字字符-- 编写迭代器 function allwords() local line = io.read() -- 当前行 local pos = 1 -- 一行中的位置 return function () -- 迭代器函数 while line do -- 只要 line 不为 nil 循环执行 -- 返回开始位置和结束位置 local start, end = string.find(line, "%w+", pos) if s then -- 是否找到一个单词 pos = e + 1 -- 找到一个单词,则移到这个单词的下一个位置 return string.sub(line, s) -- 返回该单词 else line = io.read() -- 这一行没找到,尝试读取下一行 pos = 1 end end return nil -- 没有剩余行了,遍历结束 end end -- 调用迭代器 for word in allwords() do print(word) end
closure
,开销很大for
在循环过程内保存了迭代器函数保存了 3 个值code
-- var-list 变量列表 , exp-list 表达式列表, 多个元素可用 , 逗号分割 -- 一般表达式列表只有一个元素,即只有一句对迭代器工厂的调用 for <var-list> in <exp-list> do <code block> end for k, v in pairs(t) do print(k, v) end for line in io.lines() do io.write(line, "\n") end
nil
,当它为 nil
时循环结束 for
首先会先对 in
后面的表达式求值,这些表达式应返回 3 个值供 for
保存element
nil
补足for
会以恒定状态和控制变量来调用迭代器函数for
将迭代器函数的返回值赋予变量列表中的变量 nil
,则循环终止for
执行循环体,而后再次调用迭代器函数,并重复这个过程for
构建的角度来讲,恒定状态的内容与 for
自己是彻底无关的。for
只是保存了初始化中返回的值,并在调用迭代器函数时传入该值。for var_1, ..., var_n in <exp-list> do <code clock> end -- 上述代码等价于以下代码s do -- _f 为迭代器函数,_s 为恒定状态,控制变量的初值为 a0 local _f, _s, _var = <exp-list> while true do local var_1, ... var_n = _f(_s, _var) _var = var_1 if _var == nil then break end end <code block> end
_f
为迭代器函数,_s
为恒定状态,控制变量的初值为 a₀
a₁ = f(s, a₀)
、a₂ = f(s, a₁)
以此类推ai
为 nil
结束循环for
还有其余变量,那么 他们也会在每次调用 f
后得到额外的值