resume e yield
Scambi dati tra chiamante e coroutine con resume/yield.
resume e yield è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.
Passaggio di valori alla coroutine
Gli argomenti passati alla prima chiamata di coroutine.resume diventano i parametri della funzione che costituisce il corpo della coroutine. Gli argomenti passati alle chiamate successive vengono restituiti dalla chiamata a coroutine.yield() che ha sospeso la coroutine.
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 yieldValori restituiti da yield
I valori passati a coroutine.yield(val1, val2) diventano i valori restituiti dalla chiamata a coroutine.resume() che si è fermata su yield. In questo modo, yield «restituisce» valori al chiamante.
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 doneComunicazione bidirezionale
Le coroutine consentono una vera comunicazione bidirezionale: il chiamante passa i dati tramite resume, la coroutine li elabora e restituisce i risultati tramite yield. Ogni chiamata a resume/yield è uno scambio sincrono.
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) -- 49Produttore-consumatore
Il modello classico delle coroutine: il produttore restituisce gli elementi uno alla volta tramite yield; il consumatore riprende il produttore ogni volta che ha bisogno dell'elemento successivo. Nessuno dei due procede in anticipo rispetto all'altro: la sincronizzazione è perfetta.
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)
endPipeline con le coroutine
Colleghi più coroutine in una pipeline. Ogni fase legge dalla fase precedente e restituisce valori tramite yield alla fase successiva. La fase finale esegue la pipeline riprendendo l'ultima fase, che propaga la richiesta a ritroso lungo la catena.
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 36Coroutine per simulare operazioni asincrone
Senza thread del sistema operativo, le coroutine possono simulare operazioni asincrone: esegua yield mentre «attendono» e riprenda la coroutine quando il «risultato» è pronto. Uno scheduler riprende la coroutine passando il risultato.
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 all'interno di una funzione
È possibile eseguire yield dall'interno di qualsiasi funzione chiamata da una coroutine, non solo dalla funzione di livello superiore. L'operazione yield risale attraverso tutte le chiamate annidate fino alla chiamata a resume. Questo è detto «stack di chiamate sospeso».
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:2Le coroutine non sono thread
Le coroutine di Lua non sono thread del sistema operativo. Viene eseguita una sola coroutine alla volta: non esistono prelazione né parallelismo. Tutte le coroutine condividono un singolo thread del sistema operativo. Per ottenere un vero parallelismo sono necessari più stati Lua in thread del sistema operativo separati.
-- 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)Stato dopo resume
Controlli lo stato della coroutine per decidere se riprenderla. Una coroutine che ha terminato l'esecuzione, cioè è uscita dal proprio corpo, è «terminata»: riprenderla restituisce false insieme a un errore. Controlli sempre lo stato prima di riprendere una coroutine nei cicli.
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: 3Più yield in una sola chiamata a resume
Una singola chiamata a coroutine.resume esegue la coroutine fino al yield successivo o fino alla sua conclusione. Non è possibile far eseguire più yield a una coroutine durante una sola chiamata a resume: ogni yield sospende la coroutine, che attende la chiamata a resume successiva.
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 endsVerifica rapida
In cosa si trasformano i valori passati a coroutine.yield(v1, v2)?
Riepilogo: resume e yield
Riepilogo:
- Argomenti della prima chiamata a resume → parametri del corpo della coroutine
- Argomenti delle chiamate successive a resume → restituiti dal yield() precedente
- Argomenti di yield → restituiti dalla chiamata a resume() che ha attivato yield
- Bidirezionalità: ogni resume/yield è uno scambio
- È possibile eseguire yield da qualsiasi funzione annidata
- Le coroutine sono cooperative, non parallele
Domande Frequenti
La lezione «resume e yield» è gratuita?
Sì — il testo completo di «resume e yield» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.
Cosa imparerò in «resume e yield»?
Scambi dati tra chiamante e coroutine con resume/yield. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Lua Academy?
Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «resume e yield»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Lua Academy?
Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.