Читал про генераторы из книги PHP 7 Котерова, наткнулся на такой пример: PHP: function collect($arr, $callback) { foreach ($arr as $value) { yield $callback($value); } } $arr = [1, 2, 3, 4, 5, 6]; $collect = collect($arr, function($e){ return $e * $e; }); foreach ($collect as $val) echo "$val "; // 1 4 9 16 25 36 В данном примере используется: yield, анонимные функции и замыкания Но... зачем? Ведь аналогичный результат можно получить и с одним foreach: PHP: function test($arr) { $result = ''; foreach ($arr as $t) { $result .= ($t * $t).' '; } return $result; } $arr = [1, 2, 3, 4, 5, 6]; echo test($arr); // 1 4 9 16 25 36 Кто-то может ответить, что мол раздел про генераторы, вот и пример сделали с yield, но у меня на такой ответ резонное возражение - почему нельзя было показать пример, где применение yield и всех других наворотов действительно оправданно. А данный пример из книги вызывает лишь отвращение - функционал примитивный, но код как будто специально переусложнен. Как будто его автор специально писал код так, чтобы в нем было трудно разобраться другому программисту. Может быть кто-то скажет, как дополнить функционал, с которым пример из книги справится легко, и без всех этих наворотов никак не обойтись?
Прости Котерова Написать хороший пример очень сложно, т.к. надо соблюсти противоречивые требования: - избегать сущностей, не относящихся к теме и - оно должно делать что-то годное этакий Minimal Viable Product в 10 строк. В моём понимании генератор это логическое развитие класса-итератора. Поэтому начни с поиска полезных итераторов.
@Walk, пример просто призван показать, как работает генератор. Это надо просто знать, а в один прекрасный момент может в голове щёлкнуть: а не зафигачить ли здесь генератор. Я так понимаю, они полезны, если функция вычисляет (получает) ряд значений, и эти действия достаточно ресурсоёмкие или времяёмкие. При этом генераторы позволяют вернуть каждое значение вызывающему коду, чтоб он сразу что-то с ним сделал, не дожидаясь следующего. Даже в этом примере они были бы полезны, если в функцию collect передать не возведение в квадрат, а какую-то ресурсоёмкую функцию. Можно, к примеру, результаты SQL-запроса возвратить генератором, тогда не нужно будет тратить память на сохранения их всех в массиве. При больших запросах может пригодиться. Вроде @romach давал ссылку на что-то подобное в Laravel, но сейчас найти не могу. --- Добавлено --- О, нашёл. https://laravel.com/docs/5.4/eloquent#chunking-results, раздел "Using cursor"