<?php
function generator(): Generator
{
echo "Я генератор!\n";
for ($i = 1; $i <= 3; $i++) {
yield $i;
}
}
// Инициализируем генератор
$generator = generator();
// Перематываем генератор к началу первого выражения yield,
// если генератор ещё не там
$generator->rewind(); // Я генератор!
// В этом месте ничего не произойдёт; генератор уже перемотался к первому yield
$generator->rewind(); // Ничего не выводит, возвращает NULL
// Цикл возвращает генератор к первому выражению yield,
// если генератор ещё не там, и начинает итерацию по генератору
foreach ($generator as $value) {
// После выдачи первого значения генератор остается
// на первом выражении yield, пока не возобновит выполнение и не продвинется к следующем yield
echo $value, PHP_EOL; // 1
break;
}
// Снова возобновляем работу генератора и «отматываем» к первому выражению yield.
// Слово «отматываем» в кавычках, потому что генератор уже на первом yield.
// Ошибка не возникает, поскольку генератор ещё не продвинулся дальше первого yield
$generator->rewind();
echo $generator->current(), PHP_EOL; // 1
// Ошибка тоже не возникает, генератор всё ещё на первом выражении
$generator->rewind();
// Этот вызов продвигает генератор ко второму выражению yield
$generator->next();
try {
// Попытка перемотать генератор выбросит исключение Exception,
// потому что генератор уже перешёл ко второму выражению yield
$generator->rewind(); // Fatal error: Uncaught Exception: Cannot rewind a generator that was already run
} catch (Exception $e) {
echo $e->getMessage();
}
?>
Результат выполнения приведённого примера:
Я генератор!
1
1
Cannot rewind a generator that was already run