За последние 24 часа нас посетили 30836 программистов и 1477 роботов. Сейчас ищут 1149 программистов ...

В чем смысл данного примера из книги?

Тема в разделе "PHP для новичков", создана пользователем Walk, 1 фев 2018.

  1. Walk

    Walk Активный пользователь

    С нами с:
    7 сен 2008
    Сообщения:
    452
    Симпатии:
    86
    Читал про генераторы из книги PHP 7 Котерова, наткнулся на такой пример:

    PHP:
    1. function collect($arr, $callback) {
    2.     foreach ($arr as $value) {
    3.         yield $callback($value);
    4.     }
    5. }
    6.  
    7. $arr = [1, 2, 3, 4, 5, 6];
    8. $collect = collect($arr, function($e){ return $e * $e; });
    9. foreach ($collect as $val) echo "$val "; // 1 4 9 16 25 36
    В данном примере используется: yield, анонимные функции и замыкания

    Но... зачем? Ведь аналогичный результат можно получить и с одним foreach:

    PHP:
    1. function test($arr) {
    2.     $result = '';
    3.     foreach ($arr as $t) {
    4.         $result .= ($t * $t).' ';
    5.     }
    6.     return $result;
    7. }
    8.  
    9. $arr = [1, 2, 3, 4, 5, 6];
    10. echo test($arr); // 1 4 9 16 25 36
    Кто-то может ответить, что мол раздел про генераторы, вот и пример сделали с yield, но у меня на такой ответ резонное возражение - почему нельзя было показать пример, где применение yield и всех других наворотов действительно оправданно.

    А данный пример из книги вызывает лишь отвращение - функционал примитивный, но код как будто специально переусложнен. Как будто его автор специально писал код так, чтобы в нем было трудно разобраться другому программисту.

    Может быть кто-то скажет, как дополнить функционал, с которым пример из книги справится легко, и без всех этих наворотов никак не обойтись?
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Прости Котерова :D
    Написать хороший пример очень сложно, т.к. надо соблюсти противоречивые требования:
    - избегать сущностей, не относящихся к теме и
    - оно должно делать что-то годное
    этакий Minimal Viable Product в 10 строк.

    В моём понимании генератор это логическое развитие класса-итератора. Поэтому начни с поиска полезных итераторов.
     
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @Walk, пример просто призван показать, как работает генератор. Это надо просто знать, а в один прекрасный момент может в голове щёлкнуть: а не зафигачить ли здесь генератор. Я так понимаю, они полезны, если функция вычисляет (получает) ряд значений, и эти действия достаточно ресурсоёмкие или времяёмкие. При этом генераторы позволяют вернуть каждое значение вызывающему коду, чтоб он сразу что-то с ним сделал, не дожидаясь следующего. Даже в этом примере они были бы полезны, если в функцию collect передать не возведение в квадрат, а какую-то ресурсоёмкую функцию.

    Можно, к примеру, результаты SQL-запроса возвратить генератором, тогда не нужно будет тратить память на сохранения их всех в массиве. При больших запросах может пригодиться. Вроде @romach давал ссылку на что-то подобное в Laravel, но сейчас найти не могу.
    --- Добавлено ---
    О, нашёл. https://laravel.com/docs/5.4/eloquent#chunking-results, раздел "Using cursor"