resume i yield
Proszę wymieniać dane między wywołującym a korutyną za pomocą resume/yield.
resume i yield to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.
Przekazywanie wartości do korutyny
Argumenty przekazane do pierwszego wywołania coroutine.resume stają się parametrami funkcji będącej ciałem korutyny. Argumenty przekazane do kolejnych wznowień są zwracane przez wywołanie coroutine.yield(), które wstrzymało korutynę.
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 yieldWartości z yield
Wartości przekazane do coroutine.yield(val1, val2) stają się wartościami zwracanymi przez wywołanie coroutine.resume(), które wstrzymało się na yield. Oznacza to, że yield „zwraca” wartości do kodu wywołującego.
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 doneKomunikacja dwukierunkowa
Korutyny umożliwiają prawdziwą komunikację dwukierunkową: kod wywołujący przekazuje dane za pomocą resume, korutyna je przetwarza i przekazuje wyniki z powrotem za pomocą yield. Każda para resume/yield jest synchroniczną wymianą danych.
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) -- 49Producent–konsument
Klasyczny wzorzec użycia korutyn: producent zwraca elementy pojedynczo za pomocą yield, a konsument wznawia producenta, gdy potrzebuje kolejnego elementu. Żaden z nich nie wyprzedza drugiego — zapewnia to idealną synchronizację.
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)
endPotok z korutynami
Połącz wiele korutyn w potok. Każdy etap odczytuje dane z poprzedniego etapu i przekazuje je do następnego za pomocą yield. Ostatni etap napędza potok, wznawiając ostatnią korutynę, co uruchamia kaskadę wywołań z powrotem przez cały łańcuch.
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 36Korutyny do symulowania operacji asynchronicznych
Bez wątków systemu operacyjnego korutyny mogą symulować operacje asynchroniczne: wykonują yield podczas „oczekiwania”, a następnie są wznawiane, gdy „wynik” jest gotowy. Harmonogram wznawia korutynę, przekazując jej wynik.
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 wewnątrz funkcji
Można wykonać yield wewnątrz dowolnej funkcji wywołanej przez korutynę, a nie tylko wewnątrz funkcji najwyższego poziomu. Yield przechodzi przez wszystkie zagnieżdżone wywołania aż do resume. Nazywa się to „wstrzymanym stosem wywołań”.
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:2Korutyny to nie wątki
Korutyny Lua nie są wątkami systemu operacyjnego. W danym momencie działa tylko jedna korutyna — nie ma wywłaszczania ani równoległości. Wszystkie korutyny współdzielą jeden wątek systemu operacyjnego. Do uzyskania prawdziwego przetwarzania równoległego potrzebnych jest wiele stanów Lua działających w osobnych wątkach systemu operacyjnego.
-- 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)Stan po wznowieniu
Należy sprawdzać stan korutyny, aby zdecydować, czy można wznowić ją ponownie. Korutyna, która zakończyła działanie, czyli zwróciła wynik ze swojego ciała, jest „zakończona” — wznowienie jej zwraca false i komunikat błędu. W pętlach należy zawsze sprawdzać stan przed wznowieniem.
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: 3Wiele wywołań yield w jednym resume
Pojedyncze wywołanie coroutine.resume uruchamia korutynę aż do napotkania następnego yield albo do jej zakończenia. Nie można sprawić, by korutyna wykonała yield wiele razy podczas jednego resume — każde yield wstrzymuje korutynę i oczekuje na kolejne resume.
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 endsSzybkie sprawdzenie
W co stają się wartości przekazane do coroutine.yield(v1, v2)?
Podsumowanie: resume i yield
Podsumowanie:
- Argumenty pierwszego resume → parametry ciała korutyny
- Argumenty kolejnych resume → wartości zwracane przez poprzednie yield()
- Argumenty yield → wartości zwracane przez resume(), które wywołało dane yield
- Dwukierunkowość: każda para resume/yield jest wymianą danych
- yield działa także z dowolnej zagnieżdżonej funkcji
- Korutyny działają kooperatywnie, a nie równolegle
Często zadawane pytania
Czy lekcja „resume i yield” jest bezpłatna?
Tak — pełny tekst „resume i yield” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „resume i yield”?
Proszę wymieniać dane między wywołującym a korutyną za pomocą resume/yield. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Lua Academy?
Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „resume i yield”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?
Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.