你应该知道的 PHP yield from 知识 ( 下 )
在 你应该知道的 PHP yield 知识 ( 中 ) 中我们了解了 yield 关键字的使用方式。知道了 yield 关键字是 PHP 生成器的核心。 但是呢?上一章节中我们所有使用 yield 的方式都是 yield 当前作用域范围内的值,但如果 yield 的值是另一个生成器生成的值又要怎么做呢 ?
在 PHP 5 中,这是没办法的事情,但在 PHP 7 中,PHP 的核心开发人员已经意识到了这个问题,新增了 yield from
语句来 yield 另一个生成器生成的值。
yield from 语句
PHP 7 中,生成器允许我们使用 yield from
语句将值的生成委托给另一个生成器,Traversable
对象或数组。
也就是说,外部生成器将从内部生成器,对象或数组中生成所有值,直到它不再有效,之后将在外部生成器中继续执行。
如果生成器与 yield from
一起使用,那么 yield from
语句将会返回内部生成器返回的任何值。
范例 一
我们看一个简单的示例,演示了如何使用 yield from 语句
<?php function from() { echo "from 1:\n"; yield 1; echo "from 2:\n"; yield 2; echo "from 3:\n"; yield 3; } function gen() { yield 0; yield from from(); yield 4; } foreach ( gen() as $v ) { var_dump($v); }
运行结果如下
[yufei@www.twle.cn helloworld]$ php d.php int(0) from 1: int(1) from 2: int(2) from 3: int(3) int(4)
可以看到,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() as $num) { echo "$num "; }
大家猜猜,输出结果是什么
1 2 3 4 5 6 7 8 9 10
范例三: 当 yield from 遇上了 return
yield from 也可以和 return 语句一起使用。大家猜猜下面的输出结果是什么?
<?php function count_to_ten() { yield 8; return yield from nine_ten(); } function nine_ten() { yield 9; return 10; } $gen = count_to_ten(); foreach ($gen as $num) { echo "$num "; }
输出结果为
8 9
是不是很好奇,那个 return 10
返回的 10 到哪里去了 ? 有关这 10 的去向,我们会再拿一个章节来说明