Ответ
Метод, использующий yield, возвращает объект встроенного класса Generator.
Generator — это внутренний класс, реализующий интерфейсы Iterator и Traversable. Это означает, что возвращаемый объект можно использовать в цикле foreach.
Пример с явным указанием типа (PHP 7.0+):
function generateSequence(int $start, int $end): Generator {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
$gen = generateSequence(1, 5);
var_dump($gen instanceof Generator); // bool(true)
echo get_class($gen); // Generator
foreach ($gen as $value) {
echo $value . ' '; // 1 2 3 4 5
}
Ключевые особенности:
- Ленивые вычисления: Значения генерируются по требованию, а не все сразу, что экономит память.
- Итератор: Объект
Generatorуправляет своим состоянием (текущее значение, ключ, возможность продолжения). - Двусторонняя коммуникация: Через
Generator::send($value)можно передавать значения в генератор, аyieldможет возвращать их.
Важно: Нельзя использовать return для возврата значения из такой функции в PHP < 7.0. В PHP 7.0+ return может использоваться для завершения генератора и установки его конечного возвращаемого значения, доступного через $gen->getReturn().
Ответ 18+ 🔞
Слушай, а вот насчёт этих генераторов в пыхе — это вообще отдельная песня, ёпта. Представь себе: есть у тебя функция, которая вместо того чтобы нагло вывалить на тебя весь массив данных и сожрать всю оперативку, как последняя свинья, просто лениво плюётся значениями по одному, когда ты её об этом просишь. И возвращает она не просто что-то, а объект встроенного класса Generator.
Этот Generator — он такой хитрожопый внутренний класс, который прикидывается и Iterator, и Traversable одновременно. Короче, его можно тупо в foreach воткнуть, и он отработает как надо.
Вот смотри, как это выглядит, если ты любитель явно указывать типы (PHP 7.0+):
function generateSequence(int $start, int $end): Generator {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
$gen = generateSequence(1, 5);
var_dump($gen instanceof Generator); // bool(true)
echo get_class($gen); // Generator
foreach ($gen as $value) {
echo $value . ' '; // 1 2 3 4 5
}
А теперь главные фишки, из-за которых это всё вообще стоит использовать:
- Ленивые вычисления, ядрёна вошь! Значения не генерируются все сразу, а только тогда, когда ты их реально запросил. Памяти жрёт — ноль ебать, особенно если данных овердохуища.
- Он сам себе итератор. Этот объект
Generatorсам помнит, на каком он значении, какой ключ и можно ли двигаться дальше. Умная штука, бля. - Двустороннее движение, ёбана! Ты можешь не только получать от него значения, но и пихать их обратно через
Generator::send($value). Аyieldв этот момент может их принимать и возвращать. Настоящий диалог получается, а не просто монолог.
Важный момент, чувак: В пыхе до седьмой версии использовать return в такой функции для возврата значения — это была идея хуй с горы. Ничего не работало. А вот начиная с PHP 7.0, return можно юзать, чтобы красиво завершить генератор и задать финальное возвращаемое значение. Достать его потом можно через $gen->getReturn(). Вот такая вот эволюция, бля.