Che cosa è yield
?
La yield
parola chiave restituisce i dati da una funzione del generatore:
Il cuore di una funzione del generatore è la parola chiave yield. Nella sua forma più semplice, un'istruzione yield assomiglia molto a un'istruzione return, tranne per il fatto che invece di interrompere l'esecuzione della funzione e restituirla, yield fornisce invece un valore al codice che scorre ciclicamente sul generatore e mette in pausa l'esecuzione della funzione generatore.
Cos'è una funzione generatore?
Una funzione di generatore è effettivamente un modo più compatto ed efficiente per scrivere un Iteratore . Ti permette di definire una funzione (la tua xrange
) che calcolerà e restituirà i valori mentre ci stai passando sopra :
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
Ciò creerebbe il seguente output:
0 => 1
1 => 2
…
9 => 10
Puoi anche controllare $key
in foreach
in usando
yield $someKey => $someValue;
Nella funzione generatore, $someKey
è quello che vuoi apparire $key
ed $someValue
essere il valore in $val
. Nell'esempio della domanda questo è $i
.
Qual è la differenza rispetto alle normali funzioni?
Ora potresti chiederti perché non stiamo semplicemente usando la range
funzione nativa di PHP per ottenere quell'output. E hai ragione. L'output sarebbe lo stesso. La differenza è come siamo arrivati lì.
Quando usiamo range
PHP, eseguirà esso, creare l'intera matrice di numeri in memoria e return
che intero array al foreach
ciclo che poi andare su di esso ed emettere i valori. In altre parole, foreach
funzionerà sull'array stesso. La range
funzione e l' foreach
unico "discorso" una volta. Pensalo come ottenere un pacco per posta. Il fattorino ti consegnerà il pacco e partirà. E poi scartate l'intero pacchetto, tirando fuori tutto quello che c'è dentro.
Quando usiamo la funzione generatore, PHP entrerà nella funzione e la eseguirà fino a quando non incontra la fine o una yield
parola chiave. Quando incontra a yield
, restituirà quindi qualunque sia il valore in quel momento nel ciclo esterno. Quindi ritorna nella funzione generatore e continua da dove ha ceduto. Dal momento che il tuo xrange
detiene un for
loop, verrà eseguito e cederà fino al $max
raggiungimento. Pensalo come il foreach
e il generatore che gioca a ping pong.
Perché ne ho bisogno?
Ovviamente, i generatori possono essere utilizzati per aggirare i limiti di memoria. A seconda del tuo ambiente, fare una range(1, 1000000)
volontà fatale lo script mentre lo stesso con un generatore funzionerà bene. O come dice Wikipedia:
Poiché i generatori calcolano i loro valori ottenuti solo su richiesta, sono utili per rappresentare sequenze che sarebbero costose o impossibili da calcolare in una sola volta. Questi includono ad esempio sequenze infinite e flussi di dati live.
I generatori dovrebbero anche essere piuttosto veloci. Ma tieni presente che quando parliamo velocemente, di solito parliamo di numeri molto piccoli. Quindi, prima di scappare e cambiare tutto il codice per utilizzare i generatori, fai un benchmark per vedere dove ha senso.
Un altro caso d'uso per i generatori sono le coroutine asincrone. La yield
parola chiave non solo restituisce valori, ma li accetta anche. Per i dettagli, consultare i due eccellenti post sul blog collegati di seguito.
Da quando posso usare yield
?
I generatori sono stati introdotti in PHP 5.5 . Cercare di utilizzare yield
prima di quella versione comporterà vari errori di analisi, a seconda del codice che segue la parola chiave. Quindi, se ricevi un errore di analisi da quel codice, aggiorna il tuo PHP.
Fonti e ulteriori letture:
yeild
una soluzione come questa: ideone.com/xgqevM