Корутины
Знакомимся с корутинами — способом приостанавливать и возобновлять функции.
Корутина — это функция, которую можно поставить на паузу в любой момент и позже продолжить с того же места, сохранив все локальные переменные.
Обычная функция выполняется от начала до конца за один раз. Корутина может прерваться посередине, отдать управление, а потом продолжить. Это незаменимо для пошаговых сценариев в играх: диалоги, анимации, поведение врагов «по шагам».
Четыре главные операции
| Функция | Что делает |
coroutine.create | создаёт корутину из функции |
coroutine.resume | запускает или продолжает её |
coroutine.yield | ставит корутину на паузу |
coroutine.status | сообщает её состояние |
Простой пример
local co = coroutine.create(function()
print("шаг 1")
coroutine.yield() -- пауза
print("шаг 2")
coroutine.yield() -- пауза
print("шаг 3")
end)
coroutine.resume(co) -- печатает шаг 1
coroutine.resume(co) -- печатает шаг 2
coroutine.resume(co) -- печатает шаг 3Вывод:
шаг 1 шаг 2 шаг 3
Каждый resume продолжает корутину до следующего yield. Между вызовами корутина «спит», сохраняя своё место.
Передача значений
Через yield и resume можно передавать данные туда-обратно:
local gen = coroutine.create(function()
for i = 1, 3 do
coroutine.yield(i * 10)
end
end)
print(coroutine.resume(gen))
print(coroutine.resume(gen))
print(coroutine.resume(gen))Вывод:
true 10 true 20 true 30
resume возвращает true и значение, переданное в yield — получается генератор последовательности.
Состояния корутины
suspended <-- на паузе, готова к resume
running <-- сейчас выполняется
dead <-- завершилась, resume больше не сработаетКак работает под капотом
Корутины Lua — это кооперативная многозадачность, а не настоящие потоки. Только одна корутина выполняется в каждый момент, и переключение происходит лишь добровольно — через yield. Поэтому здесь нет гонок данных и блокировок, как в обычной многопоточности: корутина сама решает, когда уступить. Именно так Roblox реализует wait() в скриптах.
Частые ошибки
- Звать
resumeу мёртвой (dead) корутины — это вернётfalseи сообщение об ошибке. - Путать корутины с настоящими потоками и ждать параллельного исполнения — они кооперативные.
- Забыть, что
yieldможно вызывать только внутри корутины, а не в главном коде.
Итог
- Корутина — функция, которую можно ставить на паузу через
yieldи продолжать черезresume. - Основные функции:
create,resume,yield,status. - Через
yield/resumeпередаются значения — удобно для генераторов. - Это кооперативная многозадачность: одновременно работает лишь одна корутина, без гонок данных.