Генераторы на PHP |

генераторы.png

Время от времени мы сталкиваемся с проблемами, когда приложения PHP потребляют довольно много памяти и неэффективно используют память из-за того, как мы пишем наши приложения, или когда мы не используем некоторые функции, предоставляемые самим PHP, которые помогают управлять памятью. . Примером функции, которую можно использовать в качестве преимущества для сокращения использования памяти, являются генераторы. Ты сказал Что? Да — Генераторы! Итак, углубляемся…

Что такое Генераторы?

Генераторы — это в основном функции, которые возвращают множество значений, которые можно повторять. В отличие от перебора массива, вы можете контролировать процесс перебора значений, возвращаемых генератором. Другими словами, мы можем контролировать итерацию значений и делать такие вещи, как возврат значений, когда мы хотим или столько, сколько мы хотим, или приостанавливать итерацию, или даже перематывать итерацию и переводить ее на другой уровень, мы можем отправлять значения обратно через генераторы.

В отличие от обычной функции, которая напрямую returns что-то генератор yields что-то, хотя PHP 7 теперь поддерживает функции, выдающие значения, а также возвращающие значения, но такая функция по-прежнему считается генератором. Когда yield появляется в теле функции, PHP распознает такую ​​функцию как Генератор.

Помещение объяснения в код

У нас есть наша нормальная функция с return как это:

<?php 
  function foo($a, $b) { return $a + $b; }

Но такая функция, как приведенная ниже, считается не функцией, а генератором:

<?php 
  function bar($a, $b) { yield $a + $b; }

Чтобы доказать это, я буду использовать этот код:

<?php 
  function foo($a, $b) { 
    	return $a + $b; 
    } 
    
    function bar($a, $b) { 
    	yield $a + $b; 
    } 
    
    var_dump(foo(2, 3)); 
    echo PHP_EOL; 
    var_dump(bar(2, 3));

Когда я запускаю это, я получил такой результат:

int(5) class Generator#1 (0) {
}

Вызов функции foo(2, 3) возвращается int(5) как и ожидалось, но вызов функции bar(2, 3) возвращает экземплярGenerator учебный класс. Ясно видно, что единственная разница в теле функции — это yield ключевое слово, используемое вместо return ключевое слово. Итак, подводя итог, каждый раз, когда вы используете yield ключевое слово в функции, PHP автоматически воспринимает его как Generator и он возвращает объект Generator.

Но как нам получить доступ к значению генератора?

Класс генератора реализует IteratorInterface который предоставляет несколько методов, которые можно использовать для доступа к значениям в Генераторе. Вы можете прочитать о IteratorInterfaceздесь.

Чтобы доказать это, мы добавим это в наш исходный код:

<?php 
  function foo($a, $b) { 
    	return $a + $b; 
    } 
    
    function bar($a, $b) { 
    	yield $a + $b; 
    } 
    
    var_dump(foo(2, 3)); 
    echo PHP_EOL; 
    var_dump(bar(2, 3)); 
    echo PHP_EOL; 
    var_dump(bar(2, 3) instanceof Iterator);

И получаем результат ниже:

int(5) class Generator#1 (0) {
} 

bool(true)

Мы получаем true это означает, что класс Generator реализует интерфейс Iterator.

Получение результата

Теперь, если мы позвоним ->current() метод на bar(2, 3) вызов функции так:

<?php 
  
    echo PHP_EOL; 
    var_dump(bar(2, 3)->current());

Мы получим ожидаемое int(5) как результат. Мы смогли воспользоваться ->current() потому что класс Generator реализовал Iterator интерфейс.

Как видно из документации Iterator здесьдругие методы, к которым можно получить доступ, next(), previous(), key() а также valid(), документация объясняет работу этих методов, а также их возвращаемые значения. Я рекомендую вам прочитать больше об этом.

Другой пример

В исходном примере мы yielded только один результат, но генератор на самом деле позволяет получить много результатов, давайте посмотрим на пример:

<?php 
  function compute($x, $y) { 
    	yield $x + $y; 
        yield $x * $y; 
        yield $x / $y; 
        yield $x - $y; 
    }

Приведенная выше функция вычисляет сложение, вычитание, умножение и деление двух чисел. Теперь давайте получим результат, добавив это в наш код:

<?php 
  
  $computation = compute(2, 3);
    $addition = $computation->current();
    
    echo "Addition: $addition" . PHP_EOL; 
    
    $computation->next(); 
    $multiplication = $computation->current(); 
    
    echo "Multiplication: $multiplication" . PHP_EOL; 
    
    $computation->next(); 
    $division = $computation->current(); 
    
    echo "Division: $division" . PHP_EOL; 
    $computation->next(); 
    
    $subtraction = $computation->current(); 
    
    echo "Subtraction: $subtraction" . PHP_EOL; 
    

Эта инфраструктура — это то, что обеспечивает гибкость и мощность генераторов, которые можно использовать во многих случаях, что помогает программе, которую мы пишем, во многих отношениях, таких как скорость, управление памятью, потоковая передача и т. д.

В этой статье мы только рассмотрим, что такое генераторы и как мы можем их использовать, в следующих статьях я покажу, как генераторы могут помочь в экономии памяти, а в последующих статьях я объясню, как их можно использовать для улучшить скорость, а также другие приложения.

Вы можете прочитать больше о синтаксисе генератора здесь.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *