Předávání hodnot
Korutina a program, který ji spouští, si mohou předávat hodnoty. Oběma směry vedou stejná dvě místa: yield a resume.
Z korutiny ven. Co dáte do závorek coroutine.yield(…), to vrátí coroutine.resume. Eminy slepice snesou každý den jiný počet vajec:
-- Vejce za tři dny
local function kurnik()
coroutine.yield(4)
coroutine.yield(6)
coroutine.yield(5)
end
local slepice = coroutine.create(kurnik)
print(coroutine.resume(slepice))
print(coroutine.resume(slepice))
local ok, vejce = coroutine.resume(slepice)
print("Den 3: " .. vejce .. " vajec")Vypíše:
true 4
true 6
Den 3: 5 vajecresume vrací nejdřív true, což znamená, že korutina proběhla bez chyby, a za ním hodnoty z yield. Je to stejné jako u pcall z lekce o funkcích (s false se setkáte na konci této lekce). Abyste mohli s vejci počítat, zachyťte obě hodnoty: local ok, vejce = coroutine.resume(slepice).
Do korutiny. Hodnoty dovnitř předáte přes resume, za korutinou. První resume je předá parametrům funkce, stejně jako obyčejné volání. Každé další resume je předá korutině, která čeká u yield: stanou se výsledkem toho coroutine.yield():
-- Objednávka na trhu
local function objednavka(zakaznik)
print(zakaznik .. " chce dýně.")
local pocet = coroutine.yield()
print(zakaznik .. " kupuje " .. pocet .. " dýně.")
end
local nakup = coroutine.create(objednavka)
coroutine.resume(nakup, "Děda Josef")
print("Ema počítá své dýně.")
coroutine.resume(nakup, 3)Vypíše:
Děda Josef chce dýně.
Ema počítá své dýně.
Děda Josef kupuje 3 dýně.Text "Děda Josef" se při prvním resume dostal do parametru zakaznik. Trojka vyšla z coroutine.yield() do proměnné pocet. Mezitím program dělal něco jiného.
Oběma směry najednou. Korutina si často drží nějakou hodnotu a při každém resume ji aktualizuje. Ema trhá jahody a košík si pamatuje, kolik jich v něm celkem je:
-- Jahody v košíku
local function kosik()
local celkem = 0
while true do
local natrhano = coroutine.yield(celkem)
celkem = celkem + natrhano
end
end
local jahody = coroutine.create(kosik)
coroutine.resume(jahody)
local ok, celkem = coroutine.resume(jahody, 12)
print("V košíku: " .. celkem)
ok, celkem = coroutine.resume(jahody, 8)
print("V košíku: " .. celkem)Vypíše:
V košíku: 12
V košíku: 20Krok za krokem: první resume spustí funkci, celkem je 0 a korutina se zastaví u yield(celkem). Druhé resume předá dvanáctku: yield ji vrátí do proměnné natrhano, celkem je teď 12 a cyklus se vrátí k yield(celkem), které dvanáctku podá ven jako výsledek resume. Třetí resume udělá totéž s osmičkou.
Všimněte si dvou věcí. Cyklus while true do tu není nekonečný: u každého yield se zastaví a pokračuje, jen když korutinu někdo znovu spustí. Když program skončí, korutina prostě zůstane pozastavená, a to nevadí. A první resume jen dovede korutinu k prvnímu yield. Kdyby předalo 12, dvanáctka by šla do parametrů funkce kosik, která žádné nemá, a ztratila by se.
Jak psát:
Pokyny
Na soutěži o nejtěžší dýni si Emina váha pamatuje, která dýně byla zatím nejtěžší. Ve funkci vaha pod print přidejte cyklus, který běží donekonečna. V něm korutina čeká na hmotnost další dýně pomocí local hmotnost = coroutine.yield(nejtezsi), a když je hmotnost větší než nejtezsi, zapamatuje si ji. Na konci programu zvažte dýni o 12 kg: spusťte soutez pomocí resume s hodnotou 12, výsledky zachyťte do local ok, nejtezsi a nejtěžší dýni vypište takto:
Váha je připravená.
Nejtěžší: 12 kgZvažte ještě dvě dýně, o 9 kg a 15 kg, a po každé z nich vypište nejtěžší dýni. Program vypíše:
Váha je připravená.
Nejtěžší: 12 kg
Nejtěžší: 12 kg
Nejtěžší: 15 kgZačněte programovat zdarma
2/6