基于协程的生成器
使用 coroutine.wrap 创建惰性生成器序列。
基于协程的生成器 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
协程生成器的动机
闭包很适合简单的生成器。但如果生成逻辑需要嵌套循环或复杂的控制流,使用协程生成器会清晰得多。
coroutine.wrap 基础
coroutine.wrap(fn) 会返回一个函数。每次调用都会恢复协程;通过 coroutine.yield 生成的值会成为返回值。
local gen = coroutine.wrap(function()
coroutine.yield(1)
coroutine.yield(2)
coroutine.yield(3)
end)
for v in gen do print(v) end无限序列生成器
协程可以无限期地生成值,因此非常适合由调用方使用 break 终止的无限序列。
local function naturals()
return coroutine.wrap(function()
local n = 0
while true do
n = n + 1
coroutine.yield(n)
end
end)
end
for v in naturals() do
if v > 5 then break end
print(v)
end树遍历生成器
使用协程进行递归深度遍历非常简单——只需从递归调用中生成值,无需管理显式栈。
local function walkTree(node)
return coroutine.wrap(function()
local function recurse(n)
coroutine.yield(n.value)
for _, child in ipairs(n.children or {}) do
recurse(child)
end
end
recurse(node)
end)
end斐波那契生成器
斐波那契序列非常适合使用协程实现:保存两个状态变量,并生成每一项。
local function fibs()
return coroutine.wrap(function()
local a, b = 0, 1
while true do
coroutine.yield(a)
a, b = b, a + b
end
end)
end
local fib = fibs()
for i = 1, 8 do print(fib()) end向生成器传递值
恢复函数接收的参数就是 yield 的返回值,因此可以实现双向通信。
local acc = coroutine.wrap(function()
local total = 0
while true do
local n = coroutine.yield(total)
total = total + (n or 0)
end
end)
acc() -- start
print(acc(10)) -- 10
print(acc(5)) -- 15coroutine.wrap 与 coroutine.create
wrap 更简单,并且遇到错误时会抛出错误。create 会返回线程对象,您可以根据 resume 的返回值处理错误。
生成器流水线
将基于协程的生成器串联起来组成惰性流水线:生产者生成原始数据,过滤器生成匹配的元素,映射器生成转换后的元素。
错误传播
如果被包装的协程抛出错误,包装函数也会抛出错误。请将生成器调用放在 pcall 中,以便安全地使用。
内存效率
协程生成器是惰性的——它们会按需计算值。这样可以避免构建大型中间表,对于大型数据集来说是一个重要优势。
耗尽处理
当协程函数返回(而不是生成值)时,对包装函数的下一次调用会返回 nil,从而自然终止通用 for 循环。
协程生成器问题
基于 coroutine.wrap 的生成器的协程函数返回(而不是生成值)时会发生什么?
回顾:协程生成器
coroutine.wrap 会将任意协程转换为可复用的生成器函数。它支持惰性无限序列、递归遍历以及控制流清晰的流水线阶段。
常见问题解答
「基于协程的生成器」课时是免费的吗?
是的 — 「基于协程的生成器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「基于协程的生成器」这节课中我会学到什么?
使用 coroutine.wrap 创建惰性生成器序列。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「基于协程的生成器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 泛型 for 协议
- 无状态迭代器
- 使用闭包实现有状态迭代器
- 基于协程的生成器