Les langages / Lua / Coroutines et iterateurs
Coroutines
Les coroutines sont des fonctions qui peuvent être suspendues et reprises. Elles permettent la programmation coopérative, utile pour les générateurs, la gestion d'état et les tâches asynchrones.
Créer et utiliser une coroutine
-- Créer une coroutine
local co = coroutine.create(function()
print("Coroutine démarrée")
coroutine.yield() -- Pause
print("Coroutine reprise")
coroutine.yield()
print("Coroutine terminée")
end)
-- Vérifier l'état
print(coroutine.status(co)) -- suspended
-- Exécuter
coroutine.resume(co) -- Coroutine démarrée
print(coroutine.status(co)) -- suspended
coroutine.resume(co) -- Coroutine reprise
coroutine.resume(co) -- Coroutine terminée
print(coroutine.status(co)) -- dead
Échanger des valeurs avec yield/resume
-- Coroutine qui produit des valeurs
local producteur = coroutine.create(function()
for i = 1, 5 do
print("Production de", i)
local reponse = coroutine.yield(i)
print("Reçu:", reponse)
end
end)
-- Consommer les valeurs
while coroutine.status(producteur) ~= "dead" do
local ok, valeur = coroutine.resume(producteur, "ACK")
if valeur then
print("Consommation de", valeur)
end
end
Générateur avec coroutine
-- Générateur de Fibonacci
function fibonacci()
return coroutine.wrap(function()
local a, b = 0, 1
while true do
coroutine.yield(a)
a, b = b, a + b
end
end)
end
-- Utiliser le générateur
local fib = fibonacci()
for i = 1, 10 do
print(fib()) -- 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
end
-- Générateur de nombres premiers
function premiers(max)
return coroutine.wrap(function()
for n = 2, max do
local estPremier = true
for i = 2, math.sqrt(n) do
if n % i == 0 then
estPremier = false
break
end
end
if estPremier then
coroutine.yield(n)
end
end
end)
end
for p in premiers(20) do
print(p) -- 2, 3, 5, 7, 11, 13, 17, 19
end
Pipeline de traitement
-- Pipeline avec coroutines
function source(data)
return coroutine.wrap(function()
for _, v in ipairs(data) do
coroutine.yield(v)
end
end)
end
function filtrer(input, fn)
return coroutine.wrap(function()
for v in input do
if fn(v) then
coroutine.yield(v)
end
end
end)
end
function transformer(input, fn)
return coroutine.wrap(function()
for v in input do
coroutine.yield(fn(v))
end
end)
end
-- Utiliser le pipeline
local donnees = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
local resultat = transformer(
filtrer(
source(donnees),
function(x) return x % 2 == 0 end
),
function(x) return x * x end
)
for v in resultat do
print(v) -- 4, 16, 36, 64, 100
end
1 exercice pour cette lecon
Les exercices demandent un compte : il faut bien enregistrer votre progression quelque part. La lecture, elle, reste libre. Creer un compte
- Coroutine basique difficile 35 XP