上次给你们讲了PHP yield
的用法,今天给你们讲讲 yield from
。php
看到这里来,必定是 PHP.net 看得不过瘾吧,这篇文章必定把 yield from
语法给你讲透彻。git
<?php function func() { yield from $expression; }
是的,和yield
同样,这是一个生成器语法。$expression
是必须(yield 能够为空为NULL),且必须是可迭代对象。shell
<?php function yield_from_func() { (yield from array(1, 2, 3, 4)); } foreach (yield_from_func() as $value) { echo 'value is : ' . $value . PHP_EOL; }
$ php ./test.php value is : 1 value is : 2 value is : 3 value is : 4
经过以上例子,可得 yield from
能把个数组(也能够是迭代器)一个个遍历并送出来。express
<?php function yield_func() { yield 1; yield 2; yield 3; } function yield_from_func2() { (yield from yield_func()); } $gen = yield_from_func2(); echo 'value is : ' . $gen->current() . PHP_EOL; $gen->next(); echo 'value is : ' . $gen->current() . PHP_EOL; $gen->next(); echo 'value is : ' . $gen->current() . PHP_EOL; $gen->next();
$ php ./test.php value is : 1 value is : 2 value is : 3
小例子2里,yield from
右侧是生成器时, 调用next
,current
也能将生成器内的元素一个个送出。segmentfault
接下来咱们,上全量测试代码。 gitee PHP Generator Yield Demo ,探究一下yield from
的各类细节。数组
git clone https://gitee.com/xupaul/PHP-generator-yield-Demo.git
纸上得来终觉浅,绝知此事要躬行多线程
$ php ./yieldFromTest.php
// ./yieldFromFunctions.php function yield_from_func1() { // yield from ; // Parse error: syntax error, unexpected ';' }
有一行代码,被注释了,语法静态检查都不能经过。函数
上图是生成器判断运行结果,yield_from_func4()
, 有个if判断是否运行到 yield from
, PHP 依然断定为生成器。测试
其实到这里,你们一下就清楚了,是否是生成器是静态判断的。编码
<?php function yield_from_func3() { yield from 'test'; } ··· echo 'eg: NO.5' . PHP_EOL; $gen = yield_from_func3(); echo 'call yield_from_func2 current ' . PHP_EOL; // $re = $gen->current(); // Fatal error: Uncaught Error: Can use "yield from" only with arrays and Traversables echo PHP_EOL;
eg: NO.5 yield_from_func4 is PHP Generator? :true call yield_from_func2 current
这yield_from_func4
虽然断定为生成器,一执行就报错,可得 yield from
右侧必须是一个可遍历对象。
例子8也会运行出错。
以上截图,例子1,和例子2,能够看到 yield from 和 yield 的 current,获取当前值,next 跳过, send 向生成器传入值,这些功能和一半生成起都差很少的。
一样,开始时跳过current,直接调用send,会丢失第一次
yield
的弹出值。
例子:6,7.中,看到截图中例子6 get re:
打印出 $re
是 NULL
, list($re1,$re2,$re3)
一样也是NULL
.
结论: yield from 左侧不能收到任何值,在左侧写赋值语句不会报错,但也没有意义。
那么send进入的值,去哪了呢,继续看
<?php function yield_func20 () { $arr = array(); echo 'run to function ' . __FUNCTION__ . ' line: ' . __LINE__ . PHP_EOL; $arr[] = yield 2; $arr[] = yield 'key' => 'value'; $arr[] = yield 7 => 'cc'; $arr[] = yield 5; echo 'run to function ' . __FUNCTION__ . ' line: ' . __LINE__ . ', arr re: '; var_export($arr); echo PHP_EOL; }
例子:9,10中,咱们实现了,从生成器中取值。 同时经过 yield_func20
函数内 $arr
变量dump发现,向生成器 send
的值,会经过 yield from
传到内部生成器的 yield
赋值语句.
例子:12,13中,发现,yield from 是能够多层嵌套的。
yield from 的嵌套做用,是很是重要特性,在协程编码中,熟练使用嵌套能减小函数指针,以及生成器的应用传递。
yield from
是一个强大且不可缺乏的语法,若是只有 yield
那么就只是有了生成器,有了 yield from
那就有了一根强大的“针”——穿过一个个 生成器,按照call stack 把一个个生成器串了起来。 调用方法用 call_user_func()
,调用 生成器用 yield from
.
好,这就是 yield from
用法的探究,实战会放到后续文章。
欢迎提问,若是有帮助请关注,收藏,做者有新的发现,干货,也会更新文章。