使用闭包实现有状态迭代器
使用闭包构建可在多次调用之间维护状态的迭代器。
使用闭包实现有状态迭代器 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
闭包发挥作用的场景
当迭代器需要维护复杂且不断变化的状态(位置、栈、历史记录)时,闭包是自然的工具。状态会存放在上值中。
闭包迭代器模式
返回一个函数,并将状态保存在上值中。泛型 for 不提供外部状态,只会每次调用该函数。
local function chars(s)
local i = 0
return function()
i = i + 1
local c = s:sub(i, i)
return c ~= "" and c or nil
end
end
for c in chars("lua") do print(c) end文件行迭代器
经典的有状态闭包迭代器会从文件句柄中逐行生成内容,直到 EOF。
local function lines(filename)
local f = io.open(filename, "r")
return function()
local line = f:read("*l")
if not line then f:close() end
return line
end
end过滤迭代器
使用一个闭包包装现有迭代器,跳过不符合谓词的元素。
local function filtered(iter, pred)
return function()
local v = iter()
while v ~= nil and not pred(v) do
v = iter()
end
return v
end
end映射迭代器
映射迭代器会即时转换每个元素,而不会构建中间表。
local function mapped(iter, fn)
return function()
local v = iter()
if v ~= nil then return fn(v) end
end
end压缩迭代器
压缩迭代器会同时从两个迭代器中提取元素,在任一迭代器耗尽时停止。
local function zipped(iter1, iter2)
return function()
local a, b = iter1(), iter2()
if a ~= nil and b ~= nil then return a, b end
end
end链式迭代器
链式迭代器会先耗尽一个迭代器,然后切换到下一个。
local function chained(...)
local iters = {...}
local idx = 1
return function()
while idx <= #iters do
local v = iters[idx]()
if v ~= nil then return v end
idx = idx + 1
end
end
end计数迭代器
使用闭包计数器将迭代器限制为最多生成 N 个值。
local function take(n, iter)
local count = 0
return function()
count = count + 1
if count <= n then return iter() end
end
end树遍历迭代器
深度优先树遍历使用栈(作为上值的表)来维护遍历状态。
local function dfs(root)
local stack = {root}
return function()
if #stack == 0 then return nil end
local node = table.remove(stack)
for _, child in ipairs(node.children or {}) do
stack[#stack+1] = child
end
return node
end
end内存注意事项
有状态迭代器会分配一个闭包对象。对于极其紧凑的内层循环,无状态迭代器可能更合适。对于复杂遍历而言,闭包非常值得使用。
比较:有状态与无状态
- 有状态:状态复杂,支持任意遍历顺序,易于编写。
- 无状态:顺序访问简单、零分配、速度快。
有状态迭代器问题
有状态闭包迭代器将其状态存储在哪里?
回顾:有状态迭代器
基于闭包的有状态迭代器将复杂的遍历状态存储在上值中,从而支持过滤、映射、树遍历和惰性流水线,并且这些功能都可组合且节省内存。
常见问题解答
「使用闭包实现有状态迭代器」课时是免费的吗?
是的 — 「使用闭包实现有状态迭代器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「使用闭包实现有状态迭代器」这节课中我会学到什么?
使用闭包构建可在多次调用之间维护状态的迭代器。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「使用闭包实现有状态迭代器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。