<?php
// +----------------------------------------------------------------------
// | Language Reference >> Predefined Interfaces and Classes >> Generator
// +----------------------------------------------------------------------
// | Author: alexander <[email protected]>
// +----------------------------------------------------------------------
// | Datetime: 2017-11-13 17:48
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
/**
* Generator implements Iterator {
* --Methods--
* public mixed current ( void )
* public mixed getReturn ( void )
* public mixed key ( void )
* public void next ( void )
* public void rewind ( void )
* public mixed send ( mixed $value )
* public mixed throw ( Throwable $exception )
* public bool valid ( void )
* public void __wakeup ( void )
*
*/
/**
* current 返回當前產生的值
*/
function t(){
for($i=1;$i<=10;$i++){
yield $i;
}
return 100;
}
$gen = t();
//var_dump($gen->current());
var_dump($gen->getReturn());
// 輸出 int(1)
/**
* getReturn 返回生成器函數中return值
* 確保使用getReturn的時候生成器函數返回return值而不是yield值,否則會報錯;
*/
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
// 輸出:
// 1
// 2
// 3
/**
* key 返回yield值的key
* 如果沒有key,返回0
*/
$gen = (function() {
yield 1 => 2;
})();
var_dump($gen->key());
var_dump($gen->current());
// 輸出:
// int(1)int(2)
$gen = (function() {
yield 1;
})();
var_dump($gen->key());
var_dump($gen->current());
// 輸出:
// int(0)int(1)
/**
* next 生成器繼續執行
* 生成器已經執行到末尾,不會自動next到開始
*/
$gen = (function(){
yield 1;
yield 2;
yield 3;
})();
var_dump($gen->current());
$gen->next();
var_dump($gen->current());
$gen->next();
var_dump($gen->current());
$gen->next();
var_dump($gen->current());
// 輸出:
// int(1)int(2)int(3)NULL
/**
* rewind 重置生成器
* 如果生成器已經執行,則會拋出一個異常
*/
/**
* send 向生成器傳入一個值
*/
function printer()
{
while (1) {
$string = yield;
echo $string . PHP_EOL;
}
}
$printer = printer();
$printer->send('Hello world!');
$printer->send('How are you?');
// 輸出:
// Hello world!
// How are you?
//
// +----------------------------------------------------------------------
/**
* 以下是一個通過send和yield實現的雙向通信的例子,從鳥哥那裏拿來的
* 需要注意的是:
* 官網說法:send方法,向生成器傳入一個值,並且把這個值作爲當前執行yield的結果,並且繼續執行生成器;
* 也就是說,send方法做了三件事情;
* send方法返回的值很有意思,他返回生成器繼續執行的下一個yield返回的值,注意,不是本次yield表達式返回的值,一定要注意;
*/
function gen()
{
$ret = (yield 'yield1');
var_dump($ret);
$ret = (yield 'yield2');
var_dump($ret);
}
$gen = gen();
// 這裏輸出當前生成器的值,第一個yield的值:yield1
var_dump($gen->current());
// 這裏向生成器發送ret1,並且繼續執行生成器到下一個yield,執行生成器遇到gen裏面第一個var_dump,則輸出第一個yield表達式的值,即爲send傳入的值ret1;
// 這裏的var_dump($gen->send),則爲send方法的返回值,send方法的返回值爲下一個yield表達式返回的值,即爲yield2;
// 所以這裏輸出:
// string(4) "ret1" (the first var_dump in gen)
// string(6) "yield2" (the var_dump of the ->send() return value)
var_dump($gen->send('ret1'));
// 這裏向生成器發送ret2,並且繼續執行生成器,執行生成器遇到gen裏面第二個var_dump,輸出第二個yield表達式的值,即爲send傳入的值ret2;
// 由於生成器後面沒有yield表達式,所以send方法返回爲null
// 故輸出:
// string(4) "ret2" (again from within gen)
// NULL (the return value of ->send())
var_dump($gen->send('ret2'));
// 輸出:
// string(6) "yield1"
// string(4) "ret1" (the first var_dump in gen)
// string(6) "yield2" (the var_dump of the ->send() return value)
// string(4) "ret2" (again from within gen)
// NULL (the return value of ->send())
// +----------------------------------------------------------------------
/**
* throw 向生成器中拋入一個異常
*/
$gen = (function () {
try {
yield 1;
} catch (Exception $e) {
echo $e->getMessage();
}
})();
$gen->throw(new Exception('gen throw exception'));
// 輸出:
// gen throw exception
/**
* valid 檢查迭代器是否被關閉
* 當前生成器中執行到最後,則爲關閉,否則爲開啓
*/
$gen = (function () {
yield 1;
})();
var_dump($gen->valid());
$gen->next();
var_dump($gen->valid());
// 輸出:
// bool(true)bool(false)
/**
* __wakeup 拋出一個異常以表示生成器不能被序列化;
*/
$gen = (function () {
yield 1;
})();
var_dump($gen->__wakeup());
// 拋出異常
// Fatal error: Uncaught Exception: Unserialization of 'Generator' is not allowed in ...
Language Reference >> Predefined Interfaces and Classes >> Generator
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.