В Python генераторы были там с почти навсегда (2001). В PHP это немного более позднее.
Генераторы очень мощные. Посмотрим, почему.
Как это ведет?
Любая функция, которая содержит один или несколько доходность
Заявления – это генераторная функция.
В отличие от вернуть
Заявление, доходность
Заявление не останавливает выполнение функции. Это приостанавливает его исполнение. В следующий раз вы назовете функцию, она продолжается от того места, где он остановился. Весь контекст с переменными и вещами доступны!
Такое поведение идеально подходит для итерации с помощью обширного списка элементов, что является очень крутой при попытке решить математические заводы.
Генераторы в использовании
Что делать, если вам придется разбирать большие наборы данных, такие как файлы журнала. Используйте генераторы!
Вы можете зацикливаться через сумасшедшее количество итераций, не заканчивая память:
function crazyCount($limit) { for ($i = 1; $i < $limit; ++$i) { yield $i; } } foreach (crazyCount(1e8) as $total) { echo "see $total" . PHP_EOL; }
Этот скрипт сумасшедший дорого, но он не нарушает память. Время выполнения может варьироваться в зависимости от вашей машины, но это работает. Генераторы PHP реализуют класс ITERATOR PHP, который позволяет использовать удобные встроенные методы ( Текущий ()
, Next ()
) и захватывающие употребления, такие как Conoutines, многозадачность, асинхронная и параллелизм.
Но что такое генераторы, по-настоящему?
Генераторы упрощают код. Они приносят какое-то контекст казни и умные способы остановиться и идти, когда вам это нужно. доходность
Заявление похоже на кнопку паузы.
В результате функции могут содержать несколько выходов. Но это все еще совсем абстрактно, не так ли?
Привет, мир
Вы можете использовать Отправить ()
Способ отправки значений обратно к генератору, чтобы он был удобен, если вам нужно запустить некоторый анализ. Давайте сделаем Hello World:
function runBabyRun() { $miles = yield; print "counter: $miles miles". PHP_EOL; $miles = yield; print "counter: $miles miles". PHP_EOL; $miles = yield; print "counter: $miles miles". PHP_EOL; } $run = runBabyRun(); $run->send(0); print "Here we go!" . PHP_EOL; print "I am running... makes me feel good" . PHP_EOL; print "Those shoes are so cool!" . PHP_EOL; print "What a beautiful day!" . PHP_EOL; print "..." . PHP_EOL; print "..." . PHP_EOL; print "..." . PHP_EOL; print "Oh my god, I'm very far from the city, let's go back home" . PHP_EOL; $run->send(8); print "This was a nice run." . PHP_EOL; $run->send(16);
Бетонный пример в Python
Итак, теперь вы можете посмотреть, как генераторы позволяют вам остановиться и идти. В Python Generators удобно работать с большими файлами .csv с миллионами строк. Как я уже говорил в этом посте, пустыжные петли могут быть кошмаром.
Большую часть времени это связано с вредным использованием переменных, приводящих к высоким расходу памяти. Чтобы предотвратить это, используйте генераторы!
Типичное использование генераторов с .csv.
Файлы могут выглядеть следующее:
def read_export(filename): for r in open(filename, "r"): yield r
Это генераторная функция. Вместо того, чтобы вернуть строку, это дает его. Не только код короче и очиститель, но это намного эффективнее.
Он производит один элемент за раз, от одного элемента к следующему – не нужно хранить гигантский список в памяти.
Выходить за пределы
Делегация
С PHP 7 генераторы были обновлены. У нас сейчас Делегация генератора . Вы можете изолировать урожай
утверждения и используйте их в других блоках кода:
function dividers() { for ($i = 1; $i <= 212; $i++) { if (212 % $i === 0) { yield $i; } } } function misc() { yield 0; yield from dividers(); yield 777; } foreach (misc() as $g) { print $g . PHP_EOL; }
Ленивая оценка
Что делает генераторы настолько эффективными, это тот факт, что каждый элемент в списке не вычисляется в памяти, пока не используете его. Вместо того, чтобы использовать все больше и больше памяти, он использует постоянное количество памяти.
Это интеллектуальное поведение позволяет работать в высоких масштабах.
Список понимания
В Python эта техника довольно популярна:
spell_it = [ letter for letter in 'technologic' ] print( spell_it)
И я нахожу этот синтаксис красиво, он еще более читабелен, чем петля и намного гораздо более читаемое, чем карта ()
Отказ
Вы знали, что вы можете сделать почти то же самое в PHP? Следующий код (предполагающий $ сущности
это массив объектов):
$names = []; foreach ($entities as $entity) { $names[] = $entity->name; }
может быть переписан так:
$names = [foreach ($entities as $entity) yield $entity->name];
Заворачивать
PHP становится все более и более свежим вдохновением с других языков, таких как Python. Генераторы позволяют функциональному/декларативному программированию даже в PHP.
Оригинал: “https://dev.to/jmau111/make-sense-of-generators-doa”