Menu
Coddy logo textTech

Пауза с помощью 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
challenge icon

Задание

Легко

Напишите функцию 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
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Logic & Flow