Generators overview
Overzicht van generators
Generators bieden een gemakkelijke manier om eenvoudig te implementeren zonder de overhead of complexiteit van het implementeren van een klasse die de Iterator interface implementeert.
Een generator biedt een handige manier om gegevens aan foreach-lussen te leveren zonder dat je van tevoren een array in het geheugen hoeft op te bouwen, wat kan leiden tot het overschrijden van een geheugengrens of een aanzienlijke hoeveelheid verwerkingstijd vereist om te genereren. In plaats daarvan kan een generatorfunctie worden gebruikt, die hetzelfde is als een normale functie, behalve dat in plaats van één keer terug te geven, een generator zoveel keer kan yielden als nodig is om de waarden te leveren die doorlopen moeten worden. Net als bij iterators is willekeurige gegevensaccess niet mogelijk.
Een eenvoudig voorbeeld hiervan is om de range functie opnieuw te implementeren als een generator. De standaard range functie moet een array genereren met elke waarde erin en deze retourneren, wat kan resulteren in grote arrays: bijvoorbeeld, het aanroepen van range zal resulteren in meer dan 100 MB aan geheugen dat wordt gebruikt.
Als alternatief kunnen we een xrange() generator implementeren, die alleen genoeg geheugen nodig heeft om een object te maken en de huidige status van de generator intern bij te houden, wat minder dan 1 kilobyte blijkt te zijn.
Voorbeeld: Implementeren van xrange als een generator
<?php
function xrange($start, $limit, $step = 1) {
if ($start <= $limit) {
if ($step <= 0) {
throw new LogicException('Step must be positive');
}
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
} else {
if ($step >= 0) {
throw new LogicException('Step must be negative');
}
for ($i = $start; $i >= $limit; $i += $step) {
yield $i;
}
}
}
/*
* Let op dat zowel range() als xrange() hetzelfde
* resultaat opleveren hieronder.
*/
echo 'Enkele cijfers oneven getallen van range(): ';
foreach (range(1, 9, 2) as $number) {
echo "$number ";
}
echo "\n";
echo 'Enkele cijfers oneven getallen van xrange(): ';
foreach (xrange(1, 9, 2) as $number) {
echo "$number ";
}
?>
Enkele cijfers oneven getallen van range(): 1 3 5 7 9
Enkele cijfers oneven getallen van xrange(): 1 3 5 7 9
Generatorobjecten
Wanneer een generatorfunctie wordt aangeroepen, wordt er een nieuw object van de interne Generator klasse geretourneerd. Dit object implementeert de Iterator interface op een manier die veel lijkt op hoe een forward-only iteratorobject zou doen, en biedt methoden die kunnen worden aangeroepen om de status van de generator te manipuleren, inclusief het verzenden van waarden naar en het retourneren van waarden van de generator.