0Pricing
Lua Academy · Aula

resume e yield

Troque dados entre o chamador e a corrotina com resume/yield.

resume e yield é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.

Passando valores para uma corrotina

Os argumentos passados à primeira chamada de coroutine.resume tornam-se os parâmetros da função no corpo da corrotina. Os argumentos passados às retomadas seguintes são retornados pela chamada coroutine.yield() que pausou a corrotina.

local co = coroutine.create(function(a, b)
  print("received:", a, b)        -- 10  20
  local c = coroutine.yield()     -- pauses
  print("after yield:", c)        -- 30
end)

coroutine.resume(co, 10, 20)  -- first call: passes a,b
coroutine.resume(co, 30)      -- subsequent: passed to yield

Valores de yield

Os valores passados a coroutine.yield(val1, val2) tornam-se os valores retornados pela chamada coroutine.resume() que foi pausada em yield. Portanto, yield “retorna” valores para quem chamou.

local co = coroutine.create(function()
  coroutine.yield(1, "hello")
  coroutine.yield(2, "world")
  return 3, "done"
end)

local ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  1  hello

ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  2  world

ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  3  done

Comunicação bidirecional

As corrotinas permitem uma verdadeira comunicação bidirecional: quem chama passa dados por meio de resume, a corrotina os processa e devolve resultados com yield. Cada resume/yield é uma troca síncrona.

local co = coroutine.create(function(x)
  while true do
    x = coroutine.yield(x * x)  -- yield x^2, get next x
  end
end)

coroutine.resume(co)  -- start (x=nil initially)
local ok, sq
ok, sq = coroutine.resume(co, 3); print(sq)  -- 9
ok, sq = coroutine.resume(co, 5); print(sq)  -- 25
ok, sq = coroutine.resume(co, 7); print(sq)  -- 49

Produtor-consumidor

O padrão clássico de corrotinas: o produtor fornece itens um de cada vez; o consumidor retoma o produtor sempre que precisa do próximo item. Nenhum dos dois se adianta ao outro — sincronização perfeita.

local function producer(items)
  return coroutine.create(function()
    for _, item in ipairs(items) do
      coroutine.yield(item)
    end
  end)
end

local pro = producer({"apple","banana","cherry"})

-- Consumer drives the loop
while true do
  local ok, item = coroutine.resume(pro)
  if not ok or item == nil then break end
  print("consumed:", item)
end

Cadeia de processamento com corrotinas

Encadeie várias corrotinas como uma cadeia de processamento. Cada etapa lê da anterior e fornece dados à próxima por meio de yield. A etapa final conduz a cadeia retomando a última etapa, o que se propaga de volta por toda a cadeia.

local function source(items)
  return coroutine.wrap(function()
    for _, v in ipairs(items) do coroutine.yield(v) end
  end)
end

local function filter(iter, pred)
  return coroutine.wrap(function()
    for v in iter do
      if pred(v) then coroutine.yield(v) end
    end
  end)
end

local function map(iter, fn)
  return coroutine.wrap(function()
    for v in iter do coroutine.yield(fn(v)) end
  end)
end

local pipeline = map(filter(source({1,2,3,4,5,6}),
  function(n) return n%2==0 end),
  function(n) return n*n end)

for v in pipeline do io.write(v.." ") end
print()  -- 4 16 36

Corrotinas para simulação assíncrona

Sem threads do sistema operacional, as corrotinas podem simular operações assíncronas: use yield enquanto “aguarda” e retome quando o “resultado” estiver pronto. Um agendador retoma a corrotina com o resultado.

local scheduler = {}
local current = nil

local function await(key)
  coroutine.yield(key)  -- tell scheduler what we need
  return coroutine.yield()  -- wait for result
end

local co = coroutine.create(function()
  local data = await("fetch:users")
  print("Got users:", data)
end)

-- Start coroutine
local ok, want = coroutine.resume(co)
print("Coroutine wants:", want)  -- fetch:users
-- Simulate delivering the result:
coroutine.resume(co, {{name="Alice"},{name="Bob"}})

yield dentro de uma função

Você pode usar yield dentro de qualquer função chamada por uma corrotina, não apenas na função de nível superior. O yield sobe por todas as chamadas aninhadas até retornar à retomada. Isso é chamado de “pilha de chamadas suspensa”.

local function yieldTwice(label)
  coroutine.yield(label .. ":1")
  coroutine.yield(label .. ":2")
end

local co = coroutine.create(function()
  yieldTwice("A")
  yieldTwice("B")
end)

for i = 1, 4 do
  local ok, v = coroutine.resume(co)
  print(v)
end
-- A:1, A:2, B:1, B:2

Corrotinas não são threads

As corrotinas de Lua não são threads do sistema operacional. Apenas uma corrotina é executada por vez; não há preempção nem paralelismo. Todas as corrotinas compartilham uma única thread do sistema operacional. Para obter paralelismo verdadeiro, você precisa de vários estados de Lua em threads separadas do sistema operacional.

-- This is NOT parallel - interleaved execution
local function task(name, n)
  for i = 1, n do
    print(name, i)
    coroutine.yield()
  end
end

local t1 = coroutine.create(function() task("A", 3) end)
local t2 = coroutine.create(function() task("B", 3) end)

-- Must explicitly schedule:
for _ = 1, 3 do
  coroutine.resume(t1)
  coroutine.resume(t2)
end
-- A1, B1, A2, B2, A3, B3 (interleaved, NOT parallel)

status após a retomada

Verifique o status da corrotina para decidir se deve retomá-la novamente. Uma corrotina que terminou (retornou do próprio corpo) está “morta” — retomá-la retorna falso com um erro. Sempre verifique o status antes de retomar em laços.

local co = coroutine.create(function()
  for i = 1, 3 do coroutine.yield(i) end
end)

while coroutine.status(co) ~= "dead" do
  local ok, val = coroutine.resume(co)
  if ok and val ~= nil then
    print("val:", val)
  end
end
-- val: 1, val: 2, val: 3

Vários yields em uma retomada

Uma única chamada a coroutine.resume executa a corrotina até o próximo yield ou até seu término. Você não pode fazer uma corrotina produzir vários yields em uma única retomada — cada yield a suspende e aguarda a próxima retomada.

local co = coroutine.create(function()
  local x = coroutine.yield("first")
  print("got:", x)
  local y = coroutine.yield("second")
  print("got:", y)
end)

local _, v1 = coroutine.resume(co)         -- starts, yields "first"
print("yielded:", v1)                       -- first
local _, v2 = coroutine.resume(co, "a")   -- passes "a", yields "second"
print("yielded:", v2)                       -- second
coroutine.resume(co, "b")                   -- passes "b", coroutine ends

Verificação rápida

Em que se transformam os valores passados a coroutine.yield(v1, v2)?

Recapitulação: resume e yield

Resumo:

  • Argumentos da primeira retomada → parâmetros do corpo da corrotina
  • Argumentos das retomadas seguintes → retornados pelo yield() anterior
  • Argumentos de yield → retornados pelo resume() que acionou o yield
  • Bidirecional: cada resume/yield é uma troca
  • yield funciona a partir de qualquer função aninhada
  • Corrotinas: cooperativas, não paralelas

Perguntas Frequentes

A aula “resume e yield” é grátis?

Sim — o texto completo de “resume e yield” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.

O que vou aprender em “resume e yield”?

Troque dados entre o chamador e a corrotina com resume/yield. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Lua Academy?

Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “resume e yield”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Lua Academy?

Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Criando corrotinas
  2. resume e yield
  3. Estado da corrotina
  4. Padrão produtor-consumidor
← Voltar para Lua Academy