0Pricing
Lua Academy · 课时

基于协程的生成器

使用 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))   -- 15

coroutine.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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 泛型 for 协议
  2. 无状态迭代器
  3. 使用闭包实现有状态迭代器
  4. 基于协程的生成器
← 返回 Lua Academy