Що таке yield?
У 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 для досягнення цього результату. І ти прав. Вихід був би таким же. Різниця в тому, як ми потрапили туди.
Коли ми використовуємо rangePHP, виконуватиме його, створити весь масив чисел в пам'яті і 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