Che cosa è yield?
La yieldparola 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 $keyin foreachin usando
yield $someKey => $someValue;
Nella funzione generatore, $someKeyè quello che vuoi apparire $keyed $someValueessere 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 rangefunzione nativa di PHP per ottenere quell'output. E hai ragione. L'output sarebbe lo stesso. La differenza è come siamo arrivati lì.
Quando usiamo rangePHP, eseguirà esso, creare l'intera matrice di numeri in memoria e returnche intero array al foreachciclo che poi andare su di esso ed emettere i valori. In altre parole, foreachfunzionerà sull'array stesso. La rangefunzione e l' foreachunico "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 yieldparola 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 xrangedetiene un forloop, verrà eseguito e cederà fino al $maxraggiungimento. Pensalo come il foreache 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 yieldparola 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 yieldprima 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:
yeilduna soluzione come questa: ideone.com/xgqevM