Пауза с помощью coroutine.yield()
Часть раздела Logic & Flow путешествия по Lua на Coddy — урок 50 из 54.
Настоящая мощь корутин заключается в функции coroutine.yield(). Именно она позволяет корутине приостановить своё выполнение и передать управление обратно коду, который её возобновил.
Когда сопрограмма вызывает coroutine.yield(), она немедленно прекращает выполнение в этой самой точке. В следующий раз, когда вы вызовете coroutine.resume() для этой сопрограммы, она продолжит работу сразу после вызова yield(), как будто ничего не произошло.
Вот простой пример:
function countToThree()
print("One")
coroutine.yield()
print("Two")
coroutine.yield()
print("Three")
end
local co = coroutine.create(countToThree)
coroutine.resume(co) -- Выводит "One", затем приостанавливается
coroutine.resume(co) -- Выводит "Two", затем приостанавливается
coroutine.resume(co) -- Выводит "Three", затем завершаетсяОбратите внимание, как каждый вызов resume() запускает корутину до тех пор, пока она не встретит yield(). Корутина точно запоминает место, где она остановилась, включая все свои локальные переменные и состояние выполнения.
Вы также можете передавать значения обратно при приостановке выполнения. Любые аргументы, которые вы передаете в coroutine.yield(), становятся возвращаемыми значениями coroutine.resume():
function giveNumbers()
coroutine.yield(10)
coroutine.yield(20)
end
local co = coroutine.create(giveNumbers)
local status, value = coroutine.resume(co)
print(value) -- Выводит: 10
status, value = coroutine.resume(co)
print(value) -- Выводит: 20Задание
ЛегкоНапишите функцию createYieldingCoroutine, которая принимает count и возвращает строку, показывающую вывод из сопрограммы (coroutine), которая возвращает (yield) значения несколько раз.
Создайте сопрограмму, которая возвращает строку "Step X" для каждого шага от 1 до count, а затем выводит "Done" по завершении. Возобновите выполнение сопрограммы count + 1 раз, чтобы получить все возвращенные значения и финальное завершение. Верните все возвращенные значения, объединенные символом новой строки.
Логика:
- Создайте функцию, которая использует цикл для возврата (yield)
"Step 1","Step 2"и т. д. доcount - После всех возвратов функция должна завершиться (без финального yield для "Done")
- Оберните эту функцию в сопрограмму с помощью
coroutine.create() - Возобновляйте сопрограмму
countраз, собирая каждое возвращенное значение - Объедините все возвращенные значения, разделяя их символами новой строки
- Верните объединенную строку
Параметры:
count(number): Количество шагов для возврата
Возвращает: Строку, содержащую все возвращенные значения, разделенные символами новой строки (string). Формат: Step 1\nStep 2\nStep 3
Шпаргалка
Функция coroutine.yield() позволяет сопрограмме приостановить выполнение и вернуть управление вызывающей стороне. Когда coroutine.resume() вызывается снова, сопрограмма продолжает выполнение сразу после вызова yield().
Базовое использование coroutine.yield():
function countToThree()
print("One")
coroutine.yield()
print("Two")
coroutine.yield()
print("Three")
end
local co = coroutine.create(countToThree)
coroutine.resume(co) -- Выводит "One", затем приостанавливается
coroutine.resume(co) -- Выводит "Two", затем приостанавливается
coroutine.resume(co) -- Выводит "Three", затем завершаетсяПередача значений с помощью coroutine.yield():
function giveNumbers()
coroutine.yield(10)
coroutine.yield(20)
end
local co = coroutine.create(giveNumbers)
local status, value = coroutine.resume(co)
print(value) -- Выводит: 10
status, value = coroutine.resume(co)
print(value) -- Выводит: 20Аргументы, переданные в coroutine.yield(), становятся возвращаемыми значениями coroutine.resume(). Сопрограмма сохраняет все локальные переменные и состояние выполнения между вызовами yield.
Попробуйте сами
function createYieldingCoroutine(count)
-- Напишите код здесь
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордов3Продвинутые концепции функций
Возврат нескольких значенийВариативные функции (...)Функции как объекты первого классаАнонимные функцииЧто такое замыкание?Итоги — простой обработчик событий9Корутины для начинающих
Что такое корутина?coroutine create и resumeПауза с помощью coroutine.yield()resume и yieldПроверка статуса корутиныИтоги — Генератор чиселИтоги — Векторная математика