Werte übergeben
Eine Koroutine und das Programm, das sie fortsetzt, können einander Werte übergeben. Beide Richtungen laufen über dieselben zwei Stellen: yield und resume.
Aus der Koroutine heraus. Was du in die Klammern von coroutine.yield(…) schreibst, kommt aus coroutine.resume heraus. Emmas Hühner legen jeden Tag eine andere Zahl von Eiern:
-- Eier für drei Tage
local function huehnerstall()
coroutine.yield(4)
coroutine.yield(6)
coroutine.yield(5)
end
local huehner = coroutine.create(huehnerstall)
print(coroutine.resume(huehner))
print(coroutine.resume(huehner))
local ok, eier = coroutine.resume(huehner)
print("Tag 3: " .. eier .. " Eier")Das gibt Folgendes aus:
true 4
true 6
Tag 3: 5 Eierresume gibt zuerst true zurück, was bedeutet, dass die Koroutine ohne Fehler gelaufen ist, und dann die Werte aus yield. Es ist dasselbe wie bei pcall aus der Lektion über Funktionen (das false lernst du am Ende dieser Lektion kennen). Um mit den Eiern zu arbeiten, fange beide Werte auf: local ok, eier = coroutine.resume(huehner).
In die Koroutine hinein. Werte gehen über resume hinein, nach der Koroutine. Das erste resume übergibt sie an die Parameter der Funktion, wie ein gewöhnlicher Aufruf. Jedes spätere resume übergibt sie an die Koroutine, die an einem yield wartet: Sie werden zum Ergebnis dieses coroutine.yield():
-- Eine Bestellung auf dem Markt
local function bestellung(kunde)
print(kunde .. " will Kürbisse.")
local anzahl = coroutine.yield()
print(kunde .. " kauft " .. anzahl .. " Kürbisse.")
end
local verkauf = coroutine.create(bestellung)
coroutine.resume(verkauf, "Opa Josef")
print("Emma zählt ihre Kürbisse.")
coroutine.resume(verkauf, 3)Das gibt Folgendes aus:
Opa Josef will Kürbisse.
Emma zählt ihre Kürbisse.
Opa Josef kauft 3 Kürbisse.Beim ersten resume ging "Opa Josef" in den Parameter kunde. Die 3 kam aus coroutine.yield() in die Variable anzahl. Dazwischen hat das Programm etwas anderes getan.
Beide Richtungen auf einmal. Eine Koroutine behält oft einen Wert und aktualisiert ihn bei jedem resume. Emma pflückt Erdbeeren, und ihr Korb behält die Summe:
-- Erdbeeren in einem Korb
local function korb()
local gesamt = 0
while true do
local gepflueckt = coroutine.yield(gesamt)
gesamt = gesamt + gepflueckt
end
end
local erdbeeren = coroutine.create(korb)
coroutine.resume(erdbeeren)
local ok, gesamt = coroutine.resume(erdbeeren, 12)
print("Im Korb: " .. gesamt)
ok, gesamt = coroutine.resume(erdbeeren, 8)
print("Im Korb: " .. gesamt)Das gibt Folgendes aus:
Im Korb: 12
Im Korb: 20Schritt für Schritt: Das erste resume startet die Funktion, gesamt ist 0, und die Koroutine hält bei yield(gesamt) an. Das zweite resume übergibt 12: yield gibt sie in gepflueckt zurück, die Summe wird 12, und die Schleife läuft zu yield(gesamt) zurück, das die 12 als Ergebnis von resume herausgibt. Das dritte resume macht dasselbe mit 8.
Beachte zwei Dinge. Die Schleife while true do ist hier nicht endlos: Sie hält bei jedem yield an und macht nur weiter, wenn jemand die Koroutine fortsetzt. Wenn das Programm endet, bleibt die Koroutine einfach angehalten, und das ist in Ordnung. Und das erste resume bringt die Koroutine nur bis zu ihrem ersten yield. Würdest du dabei 12 übergeben, gingen die 12 an die Parameter von korb, das keine hat, und sie gingen verloren.
So schreibst du es:
Anweisungen
- 1
Beim Kürbiswettbewerb merkt sich Emmas Waage den schwersten Kürbis. Füge in
waageunter demprinteine Schleife hinzu, die ewig läuft. Darin wartet die Koroutine mitlocal gewicht = coroutine.yield(schwerster)auf das Gewicht des nächsten Kürbisses, und wenngewichtgrößer ist alsschwerster, merkt sie es sich. Wiege am Ende des Programms einen Kürbis von 12 kg: Setzewettbewerbmit12fort, fange die Ergebnisse inlocal ok, schwersterauf und gib den schwersten Kürbis so aus:Die Waage ist bereit. Schwerster: 12 kg - 2
Wiege zwei weitere Kürbisse, von 9 kg und 15 kg, und gib nach jedem den schwersten aus. Das Programm gibt aus:
Die Waage ist bereit. Schwerster: 12 kg Schwerster: 12 kg Schwerster: 15 kg