¿Qué es yield?
La yieldpalabra clave devuelve datos de una función generadora:
El corazón de una función generadora es la palabra clave de rendimiento. En su forma más simple, una declaración de rendimiento se parece mucho a una declaración de retorno, excepto que en lugar de detener la ejecución de la función y regresar, el rendimiento proporciona un valor al código que se repite sobre el generador y detiene la ejecución de la función del generador.
¿Qué es una función generadora?
Una función de generador es efectivamente una forma más compacta y eficiente de escribir un iterador . Le permite definir una función (su xrange) que calculará y devolverá valores mientras realiza un bucle sobre ella :
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
Esto crearía el siguiente resultado:
0 => 1
1 => 2
…
9 => 10
También puede controlar el $keyen el foreachmediante
yield $someKey => $someValue;
En la función de generador, $someKeyes lo que desea que aparezca $keyy $someValuees el valor en $val. En el ejemplo de la pregunta, eso es $i.
¿Cuál es la diferencia con las funciones normales?
Ahora puede preguntarse por qué no estamos simplemente usando la rangefunción nativa de PHP para lograr esa salida. Y tienes razón. La salida sería la misma. La diferencia es cómo llegamos allí.
Cuando usamos rangePHP, lo ejecutaremos, crearemos toda la matriz de números en la memoria y todareturn esa matriz en el foreachciclo que luego lo recorrerá y generará los valores. En otras palabras, foreachoperará en la matriz misma. La rangefunción y la foreachúnica "charla" una vez. Piense en ello como recibir un paquete por correo. El repartidor te entregará el paquete y se irá. Y luego desenvuelves todo el paquete, sacando lo que esté allí.
Cuando usamos la función de generador, PHP entrará en la función y la ejecutará hasta que cumpla con el final o una yieldpalabra clave. Cuando se encuentra con a yield, devolverá lo que sea el valor en ese momento al bucle externo. Luego vuelve a la función de generador y continúa desde donde cedió. Como tu xrangemantiene un forbucle, se ejecutará y cederá hasta que $maxse alcance. Piense en ello como el foreachy el generador jugando ping pong.
¿Por qué necesito eso?
Obviamente, los generadores se pueden usar para evitar los límites de memoria. Dependiendo de su entorno, hacer un range(1, 1000000)testamento fatal en su script, mientras que lo mismo con un generador funcionará bien. O como dice Wikipedia:
Debido a que los generadores calculan sus valores producidos solo bajo demanda, son útiles para representar secuencias que serían costosas o imposibles de calcular de una vez. Estos incluyen, por ejemplo, secuencias infinitas y secuencias de datos en vivo.
También se supone que los generadores son bastante rápidos. Pero tenga en cuenta que cuando hablamos de rápido, generalmente hablamos en números muy pequeños. Entonces, antes de salir corriendo y cambiar todo el código para usar generadores, haga un punto de referencia para ver dónde tiene sentido.
Otro caso de uso para generadores son las rutinas asíncronas. La yieldpalabra clave no solo devuelve valores, sino que también los acepta. Para obtener detalles sobre esto, consulte las dos excelentes publicaciones de blog vinculadas a continuación.
¿Desde cuándo puedo usar yield?
Se han introducido generadores en PHP 5.5 . Intentar usar yieldantes de esa versión generará varios errores de análisis, dependiendo del código que sigue a la palabra clave. Entonces, si obtiene un error de análisis de ese código, actualice su PHP.
Fuentes y lecturas adicionales:
yeild, digamos, una solución como esta: ideone.com/xgqevM