Qu'est-ce que c'est yield?
Le yieldmot-clé renvoie les données d'une fonction de générateur:
Le cœur d'une fonction de générateur est le mot-clé yield. Dans sa forme la plus simple, une instruction yield ressemble beaucoup à une instruction return, sauf qu'au lieu d'arrêter l'exécution de la fonction et de revenir, yield fournit à la place une valeur au code en boucle sur le générateur et suspend l'exécution de la fonction du générateur.
Qu'est-ce qu'une fonction générateur?
Une fonction de générateur est en fait un moyen plus compact et plus efficace d'écrire un itérateur . Il vous permet de définir une fonction (votre xrange) qui calculera et renverra des valeurs pendant que vous la parcourez :
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
Cela créerait la sortie suivante:
0 => 1
1 => 2
…
9 => 10
Vous pouvez également contrôler le $keydans le foreachen utilisant
yield $someKey => $someValue;
Dans la fonction de générateur, $someKeyest ce que vous voulez voir apparaître $keyet $someValueêtre la valeur $val. Dans l'exemple de la question, c'est $i.
Quelle est la différence avec les fonctions normales?
Maintenant, vous vous demandez peut-être pourquoi nous n'utilisons pas simplement la rangefonction native de PHP pour obtenir cette sortie. Et vous avez raison. La sortie serait la même. La différence, c'est comment nous y sommes arrivés.
Lorsque nous utilisons rangePHP, l'exécutons, créent le tableau entier de nombres en mémoire et returnce tableau entier dans la foreachboucle qui va ensuite le parcourir et sortir les valeurs. En d'autres termes, le foreachva fonctionner sur la baie de disques elle-même. La rangefonction et le foreachseul "parler" une fois. Pensez-y comme recevoir un colis par la poste. Le livreur vous remettra le colis et partira. Et puis vous déballez l'ensemble complet, en retirant tout ce qui s'y trouve.
Lorsque nous utilisons la fonction de générateur, PHP entrera dans la fonction et l'exécutera jusqu'à ce qu'elle rencontre la fin ou un yieldmot clé. Quand il rencontre un yield, il retournera alors quelle que soit la valeur à ce moment à la boucle externe. Ensuite, il revient dans la fonction de générateur et continue d'où il a cédé. Puisque votre xrangedétient une forboucle, il s'exécutera et cédera jusqu'à ce qu'il $maxsoit atteint. Pensez-y comme le foreachet le générateur jouant au ping-pong.
Pourquoi ai-je besoin de ça?
De toute évidence, les générateurs peuvent être utilisés pour contourner les limites de mémoire. En fonction de votre environnement, faire un range(1, 1000000)sera fatal à votre script alors que la même chose avec un générateur fonctionnera très bien. Ou, comme le dit Wikipedia:
Étant donné que les générateurs calculent leurs valeurs produites uniquement sur demande, ils sont utiles pour représenter des séquences qui seraient coûteuses ou impossibles à calculer à la fois. Il s'agit par exemple de séquences infinies et de flux de données en direct.
Les générateurs sont également censés être assez rapides. Mais gardez à l'esprit que lorsque nous parlons de rapidité, nous parlons généralement en très petit nombre. Donc, avant de vous enfuir et de modifier tout votre code pour utiliser des générateurs, faites un test pour voir où cela a du sens.
Un autre cas d'utilisation pour les générateurs est les coroutines asynchrones. Le yieldmot-clé ne renvoie pas seulement des valeurs mais il les accepte également. Pour plus de détails à ce sujet, consultez les deux excellents articles de blog liés ci-dessous.
Depuis quand puis-je utiliser yield?
Des générateurs ont été introduits en PHP 5.5 . Essayer d'utiliser yieldavant cette version entraînera diverses erreurs d'analyse, selon le code qui suit le mot clé. Donc, si vous obtenez une erreur d'analyse de ce code, mettez à jour votre PHP.
Sources et lectures complémentaires:
yeild, disons, une solution comme celle-ci: ideone.com/xgqevM