上次給你們講了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
用法的探究,實戰會放到後續文章。
歡迎提問,若是有幫助請關注,收藏,做者有新的發現,乾貨,也會更新文章。