Что такое yield
?
В yield
ключевом слове возвращает данные функции генератора:
Сердцем функции генератора является ключевое слово yield. В своей простейшей форме оператор yield очень похож на оператор return, за исключением того, что вместо остановки выполнения функции и возврата yield вместо этого предоставляет значение для кода, зацикливающегося над генератором, и приостанавливает выполнение функции генератора.
Что такое функция генератора?
Функция генератора - фактически более компактный и эффективный способ написать Итератор . Это позволяет вам определить функцию (вашу xrange
), которая будет вычислять и возвращать значения, пока вы зацикливаетесь на ней :
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
Это создаст следующий вывод:
0 => 1
1 => 2
…
9 => 10
Вы также можете управлять $key
в foreach
с помощью
yield $someKey => $someValue;
В функции генератора, $someKey
является то , что вы хотите появляться $key
и $someValue
быть значение $val
. В примере вопроса это $i
.
В чем разница с обычными функциями?
Теперь вы можете задаться вопросом, почему мы не просто используем нативную range
функцию PHP для достижения этого результата. И ты прав. Вывод будет таким же. Разница в том, как мы туда попали.
Когда мы используем range
PHP, будет выполнять его, создать весь массив чисел в памяти и return
что весь массив в foreach
цикл , который будет идти по нему и выводить значение. Другими словами, foreach
операция будет работать с самим массивом. range
Функция и foreach
только «говорить» один раз. Думайте об этом как о получении посылки по почте. Курьер доставит вам посылку и уйдет. А затем вы разворачиваете весь пакет, вынимая все, что там есть.
Когда мы используем функцию генератора, PHP входит в функцию и выполняет ее, пока она не встретит конец или yield
ключевое слово. Когда он встречает a yield
, он затем возвращает то, что является значением в то время, во внешний цикл. Затем он возвращается в функцию генератора и продолжает с того места, где он уступил. Так как ваш xrange
держит for
цикл, он будет выполняться и давать, пока не $max
будет достигнут. Думайте об этом как foreach
о генераторе, играющем в пинг-понг.
Зачем мне это нужно?
Очевидно, что генераторы можно использовать для обхода ограничений памяти. В зависимости от вашей среды выполнение range(1, 1000000)
сценария приведет к фатальному сценарию, тогда как то же самое с генератором будет работать нормально. Или, как говорит Википедия:
Поскольку генераторы вычисляют свои полученные значения только по требованию, они полезны для представления последовательностей, которые было бы дорого или невозможно вычислить сразу. К ним относятся, например, бесконечные последовательности и потоки данных в реальном времени.
Генераторы также должны быть довольно быстрыми. Но имейте в виду, что когда мы говорим о быстром, мы обычно говорим в очень небольших количествах. Поэтому, прежде чем вы сейчас запустите и измените весь свой код на использование генераторов, сделайте тест, чтобы увидеть, где это имеет смысл.
Другой вариант использования для генераторов - асинхронные сопрограммы. yield
Ключевое слово не возвращает только значение , но и принимает их. Подробнее об этом см. В двух великолепных сообщениях в блогах, ссылки на которые приведены ниже.
С каких пор я могу использовать yield
?
Генераторы были введены в PHP 5.5 . Попытка использовать yield
до этой версии приведет к различным ошибкам синтаксического анализа, в зависимости от кода, который следует за ключевым словом. Поэтому, если вы получили ошибку разбора этого кода, обновите ваш PHP.
Источники и дальнейшее чтение:
yeild
, скажем, такого решения, как это: ideone.com/xgqevM