Qu'est-ce que c'est yield
?
Le yield
mot-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 $key
dans le foreach
en utilisant
yield $someKey => $someValue;
Dans la fonction de générateur, $someKey
est ce que vous voulez voir apparaître $key
et $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 range
fonction 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 range
PHP, l'exécutons, créent le tableau entier de nombres en mémoire et return
ce tableau entier dans la foreach
boucle qui va ensuite le parcourir et sortir les valeurs. En d'autres termes, le foreach
va fonctionner sur la baie de disques elle-même. La range
fonction et le foreach
seul "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 yield
mot 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 xrange
détient une for
boucle, il s'exécutera et cédera jusqu'à ce qu'il $max
soit atteint. Pensez-y comme le foreach
et 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 yield
mot-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 yield
avant 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