Generator-syntax
Generator-syntax
En generatorfunktion ser ut precis som en vanlig funktion, förutom att istället för att returnera ett värde, kan en generator avge (yield) så många värden som behövs. Alla funktioner som innehåller yield är en generatorfunktion.
När en generatorfunktion anropas returnerar den ett objekt som kan itereras över. När du itererar över det objektet (till exempel via en foreach-loop), kommer PHP att anropa objektets iterationsmetoder varje gång det behöver ett värde. PHP sparar sedan generatorns tillstånd när generatorn avger ett värde, så att den kan återupptas när nästa värde behövs.
När det inte finns fler värden att avge, kan generatorn helt enkelt returnera, och den anropande koden fortsätter precis som om en array hade tagit slut på värden.
Notera: En generator kan returnera värden, som kan hämtas med Generator::getReturn().
yield-nyckelordet
Hjärtat av en generatorfunktion är yield-nyckelordet. I sin enklaste form ser ett yield-uttalande ut mycket som ett return-uttalande, förutom att istället för att stoppa exekveringen av funktionen och returnera, så tillhandahåller yield istället ett värde till koden som itererar över generatorn och pausar exekveringen av generatorfunktionen.
Exempel #1 Ett enkelt exempel på att avge värden
<?php function gen_one_to_three() { for ($i = 1; $i <= 3; $i++) { // Observera att $i bevaras mellan yield. yield $i; } } $generator = gen_one_to_three(); foreach ($generator som $value) { echo "$value\n"; } ?>
Ovanstående exempel kommer att ge följande output:
1 2 3
Notera: Internt kommer sekventiella heltalsnycklar att paras ihop med de avgivna värdena, precis som med en icke-associativ array.
Avge värden med nycklar
PHP stöder också associativa arrayer, och generatorer är inte annorlunda. Förutom att avge enkla värden, som visat ovan, kan du också avge en nyckel samtidigt.
Syntaxen för att avge ett nyckel/värde-par är mycket lik den som används för att definiera en associativ array, som visas nedan.
Exempel #2 Avge ett nyckel/värde-par
<?php /* * Inmatningen är semi-kolon-separerade fält, där det första * fältet är ett ID som används som nyckel. */ $input = <<<'EOF' 1;PHP;Gillar dollartecken 2;Python;Gillar blanksteg 3;Ruby;Gillar block EOF; function input_parser($input) { foreach (explode("\n", $input) som $line) { $fields = explode(';', $line); $id = array_shift($fields); yield $id => $fields; } } foreach (input_parser($input) som $id => $fields) { echo "$id:\n"; echo " $fields[0]\n"; echo " $fields[1]\n"; } ?>
Ovanstående exempel kommer att ge följande output:
1: PHP Gillar dollartecken 2: Python Gillar blanksteg 3: Ruby Gillar block
Avge null-värden
Yield kan anropas utan ett argument för att avge ett null-värde med en automatisk nyckel.
Exempel #3 Avge null-värden
<?php function gen_three_nulls() { foreach (range(1, 3) som $i) { yield; } } var_dump(iterator_to_array(gen_three_nulls())); ?>
Ovanstående exempel kommer att ge följande output:
array(3) { [0]=> NULL [1]=> NULL [2]=> NULL }
Avge genom referens
Generatorfunktioner kan avge värden genom referens såväl som genom värde. Detta görs på samma sätt som att returnera referenser från funktioner: genom att sätta ett &-tecken före funktionsnamnet.
Exempel #4 Avge värden genom referens
<?php function &gen_reference() { $value = 3; while ($value > 0) { yield $value; } } /* * Observera att vi kan ändra $number inom loopen, och * eftersom generatorn avger referenser, ändras $value * inom gen_reference(). */ foreach (gen_reference() som &$number) { echo (--$number).'... '; } ?>
Ovanstående exempel kommer att ge följande output:
2... 1... 0...
Generatordelegation via yield from
Generatordelegation gör det möjligt att avge värden från en annan generator, Traversable-objekt, eller array genom att använda yield from-nyckelordet. Den yttre generatorn kommer då att avge alla värden från den inre generatorn, objektet eller arrayen tills den inte längre är giltig, varefter exekveringen fortsätter i den yttre generatorn.
Om en generator används med yield from, kommer yield from-uttrycket också att returnera vilket värde som helst som returneras av den inre generatorn.
Varning: När man lagrar i en array (t.ex. med iterator_to_array()), återställer inte yield from nycklarna. Det bevarar nycklarna som returneras av Traversable-objektet eller arrayen. Därför kan vissa värden dela en gemensam nyckel med en annan yield eller yield from, vilket, vid insättning i en array, kommer att skriva över tidigare värden med den nyckeln.
Ett vanligt fall där detta är viktigt är när iterator_to_array() returnerar en array med nycklar som standard, vilket kan leda till oväntade resultat. iterator_to_array() har en andra parameter preserve_keys som kan sättas till false för att samla alla värden medan nycklarna som returneras av Generatorn ignoreras.
Exempel #5 yield from med iterator_to_array()
<?php function inner() { yield 1; // nyckel 0 yield 2; // nyckel 1 yield 3; // nyckel 2 } function gen() { yield 0; // nyckel 0 yield from inner(); // nycklar 0-2 yield 4; // nyckel 1 } // Skicka false som andra parameter för att få en array [0, 1, 2, 3, 4] var_dump(iterator_to_array(gen())); ?>
Ovanstående exempel kommer att ge följande output:
array(3) { [0]=> int(1) [1]=> int(4) [2]=> int(3) }
Exempel #6 Grundläggande användning av yield from
<?php function count_to_ten() { yield 1; yield 2; yield from [3, 4]; yield from new ArrayIterator([5, 6]); yield from seven_eight(); yield 9; yield 10; } function seven_eight() { yield 7; yield from eight(); } function eight() { yield 8; } foreach (count_to_ten() som $num) { echo "$num "; } ?>
Ovanstående exempel kommer att ge följande output:
1 2 3 4 5 6 7 8 9 10
Exempel #7 yield from och returvärden
<?php function count_to_ten() { yield 1; yield 2; yield from [3, 4]; yield from new ArrayIterator([5, 6]); yield from seven_eight(); return yield from nine_ten(); } function seven_eight() { yield 7; yield from eight(); } function eight() { yield 8; } function nine_ten() { yield 9; return 10; } $gen = count_to_ten(); foreach ($gen som $num) { echo "$num "; } echo $gen->getReturn(); ?>
Ovanstående exempel kommer att ge följande output:
1 2 3 4 5 6 7 8 9 10
Sidslut
Orginalhemsidan på Engelska : https://www.php.net/manual/en/language.fibers.php
PHP
Språkreferens
Språkreferens#Generatorer
Det här är en maskinöversättning av PHP-manualen till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på https://www.linux.se/kontaka-linux-se/