Generator syntax
A generator function looks just like a normal function, except that insteadof returning a value, a generator yields as many values as it needs to.
When a generator function is called, it returns an object that can beiterated over. When you iterate over that object (for instance, via a foreach loop), PHP will call the generator function each time it needs avalue, then saves the state of the generator when the generator yields avalue so that it can be resumed when the next value is required.
Once there are no more values to be yielded, then the generator functioncan simply exit, and the calling code continues just as if an array has runout of values.
Note:
A generator cannot return a value: doing so will result in a compileerror. An empty return statement is valid syntax withina generator and it will terminate the generator.
yield keyword
The heart of a generator function is the yield keyword.In its simplest form, a yield statement looks much like a returnstatement, except that instead of stopping execution of the function andreturning, yield instead provides a value to the code looping over thegenerator and pauses execution of the generator function.
Example #1 A simple example of yielding values
<?php
function gen_one_to_three() {
for ($i = 1; $i <= 3; $i++) {
// Note that $i is preserved between yields.
yield $i;
}
}
$generator = gen_one_to_three();
foreach ($generator as $value) {
echo "$value\n";
}
?>
以上例程会输出:
1
2
3
Note:
Internally, sequential integer keys will be paired with the yieldedvalues, just as with a non-associative array.
Caution
If you use yield in an expression context (for example, on the right handside of an assignment), you must surround the yield statement withparentheses. For example, this is valid:
$data = (yield $value);
But this is not, and will result in a parse error:
$data = yield $value;
This syntax may be used in conjunction with the send() method onGenerator objects.
Yielding values with keys
PHP also supports associative arrays, and generators are no different. Inaddition to yielding simple values, as shown above, you can also yield akey at the same time.
The syntax for yielding a key/value pair is very similar to that used todefine an associative array, as shown below.
Example #2 Yielding a key/value pair
<?php
/* The input is semi-colon separated fields, with the first
* field being an ID to use as a key. */
$input = <<<'EOF'
1;PHP;Likes dollar signs
2;Python;Likes whitespace
3;Ruby;Likes blocks
EOF;
function input_parser($input) {
foreach (explode("\n", $input) as $line) {
$fields = explode(';', $line);
$id = array_shift($fields);
yield $id => $fields;
}
}
foreach (input_parser($input) as $id => $fields) {
echo "$id:\n";
echo " $fields[0]\n";
echo " $fields[1]\n";
}
?>
以上例程会输出:
1:
PHP
Likes dollar signs
2:
Python
Likes whitespace
3:
Ruby
Likes blocks
Caution
As with the simple value yields shown earlier, yielding a key/value pairin an expression context requires the yield statement to beparenthesised:
$data = (yield $key => $value);
Yielding null values
Yield can be called without an argument to yield a NULL value with anautomatic key.
Example #3 Yielding NULLs
<?php
function gen_three_nulls() {
foreach (range(1, 3) as $i) {
yield;
}
}
var_dump(iterator_to_array(gen_three_nulls()));
?>
以上例程会输出:
array(3) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
}
Yielding by reference
Generator functions are able to yield values by reference as well as byvalue. This is done in the same way as returning references from functions:by prepending an ampersand to the function name.
Example #4 Yielding values by reference
<?php
function &gen_reference() {
$value = 3;
while ($value > 0) {
yield $value;
}
}
/* Note that we can change $number within the loop, and
* because the generator is yielding references, $value
* within gen_reference() changes. */
foreach (gen_reference() as &$number) {
echo (--$number).'... ';
}
?>
以上例程会输出:
2... 1... 0...
发表评论 取消回复