Generator-SyntaxEine Generatorfunktion sieht genau so aus wie eine normale Funktion mit der Ausnahme, dass ein Generator statt eines Wertes so viele Werte wie nötig zurückgibt (Stichwort: yield). Wenn eine Generatorfunktion aufgerufen wird, wird ein Objekt zurückgegeben, über das iteriert werden kann. Wenn Sie über dieses Objekt iterieren (zum Beispiel, per foreach-Schleife), wird PHP die Generatorfunktion jedesmal aufrufen, wenn ein Wert benötigt wird. Dann wird der Status des Generators gesichert, so dass fortgefahren werden kann, wenn der nächste Wert benötigt wird. Sobald keine weiteren Werte zurückgegeben werden können, kann die Generatorfunktion einfach beendet werden, und der rufende Code wird fortgesetzt, als gäbe es keine weiteren Werte in einem Array.
yield-SchlüsselwortDas Herz einer Generatorfunktion ist das yield-Schlüsselwort. In seiner einfachsten Form sieht das yield-Schlüsselwort wie eine return-Anweisung aus, ausser dass die Ausführung mit der Rückgabe nicht beendet wird, sondern yield stattdessen bei der Schleife über den Generator einen Wert für den Code bereitstellt und die Ausführung der Generatorfunktion anhält. Beispiel #1 Ein einfaches Beispiel zum liefern (yielding) von Werten
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe: 1 2 3
Achtung
Wenn Sie yield in einem Anweisungskontext nutzen (beispielsweise auf der rechten Seite einer Zuweisung), dann müssen Sie die yield-Anweisung in PHP 5 innerhalb von Klammern schreiben. Beispielsweise ist folgender Befehl gültig:
$daten = (yield $wert);
Aber dieser Befehl ist nicht gültig und wird in PHP 5 mit einem Syntaxfehler beendet:
$daten = yield $wert;
Für PHP 7 gilt die Klammerregel nicht. Diese Syntax kann in Verbindung mit der Generator::send-Methode verwendet werden. Produzieren von Werten mit SchlüsselnPHP unterstützt ebenfalls assoziative Arrays, und Generatoren unterscheiden sich nicht davon. Als Ergänzung zum Produzieren einfacher Werte, wie oben gezeigt, können Sie zur gleichen Zeit auch einen Schlüssel liefern. Die Syntax für das Produzieren eines Schlüssel/Wert-Paares ist sehr ähnlich wie die Definition von assoziativen Arrays, wie unten gezeigt. Beispiel #2 Produzieren eines Schlüssel/Wert-Paares
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe:
1:
PHP
mag Dollarzeichen
2:
Python
mag Leerzeichen
3:
Ruby
mag Blöcke
Achtung
Wie oben mit dem Zurückgeben einfacher Werte gezeigt, muss man beim Produzieren eines Schlüssel/Wert-Paares im Zuweisungskontext den yield-Befehl einklammern:
$daten = (yield $schluessel => $wert);
Produzieren von null-Werten
Yield kann ohne Argument aufgerufen werden, um einen Beispiel #3 Produzieren von
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(3) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
}
Produzieren als ReferenzGeneratorfunktionen sind genauso in der Lage Werte als Referenz zurückzugeben, wie als Wert. Dies kann in gleicher Weise erfolgen, wie beim Zurückgeben von Referenzen aus Funktionen: dies geschieht, indem dem Funktionsnamen ein Kaufmanns-Und vorangestellt wird. Beispiel #4 Produzieren von Werten als Referenz
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe: 2... 1... 0... Generatordelegation per yield fromIn PHP 7 ermöglicht die Generatordelegation mittels yield from-Ausdruck Werte von einem anderen Generator, Traversable-Objekt oder Array liefern zu lassen. Der äußere Generator liefert dann alle Werte vom inneren Generator, Objekt oder Array, bis dies nicht mehr gültig ist und die Ausführung im äußeren Generator fortfährt. Falls ein Generator mit yield from verwendet wird, gibt der yield from-Ausdruck auch alle Werte zurück, die vom inneren Generator zurückgegeben werden. Achtung
Speichern in ein Array (z.B. mit iterator_to_array)yield from setzt nicht die Schlüssel zurück. Es erhält die Schlüssel, die vom Traversable-Objekt oder Array zurückgegeben wurden. Daher können einige Werte den selben Schlüssel mit einem anderen yield oder yield from gemein haben, der, bei der Einfügung in ein Array, vorherige Werte mit diesem Schlüssel überschreibt.
Ein üblicher Fall, für den dies relevant ist, ist
iterator_to_array, das standardmäßig ein indexiertes
Array zurück gibt, was zu möglicherweise unerwarteten Ergebnissen führen
kann. iterator_to_array hat einen zweiten Parameter
Beispiel #5 yield from mit iterator_to_array
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe:
array(3) {
[0]=>
int(1)
[1]=>
int(4)
[2]=>
int(3)
}
Beispiel #6 Grundlegende Verwendung von yield from
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe: 1 2 3 4 5 6 7 8 9 10 Beispiel #7 yield from und Rückgabewerte
<?phpDas oben gezeigte Beispiel erzeugt folgende Ausgabe: 1 2 3 4 5 6 7 8 9 10 |