日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

PHP 生成器的使用詳解

瀏覽:29日期:2022-09-07 15:22:07
什么是生成器?

聽著高大上的名字,感覺像是創造什么東西的一個功能,實際上,生成器是一個用于迭代的迭代器。它提供了一種更容易的方式來實現簡單的對象迭代,相比較定義類實現Iterator接口的方式,性能開銷和復雜性大大降低。

說了半天不如直接看看代碼更直觀。

function test1(){ for ($i = 0; $i < 3; $i++) {yield $i + 1; } yield 1000; yield 1001;}foreach (test1() as $t) { echo $t, PHP_EOL;}// 1// 2// 3// 1000// 1001

就是這么簡單的一段代碼。首先,生成器必須在方法中并使用 yield 關鍵字;其次,每一個 yield 可以看作是一次 return ;最后,外部循環時,一次循環取一個 yield 的返回值。在這個例子,循環三次返回了1、2、3這三個數字。然后在循環外部又寫了兩行 yield 分別輸出了1000和1001。因此,外部的 foreach 一共循環輸出了五次。

很神奇吧,明明是一個方法,為什么能夠循環它而且還是很奇怪的一種返回循環體的格式。我們直接打印這個 test() 方法看看打印的是什么:

// 是一個生成器對象var_dump(test1());// Generator Object// (// )

當使用了 yield 進行內容返回后,返回的是一個 Generator 對象。這個對象就叫作生成器對象,它不能直接被 new 實例化,只能通過生成器函數這種方式返回。這個類包含 current() 、 key() 等方法,而且最主要的這個類實現了 Iterator 接口,所以,它就是一個特殊的迭代器類。

Generator implements Iterator { /* 方法 */ public current ( void ) : mixed public key ( void ) : mixed public next ( void ) : void public rewind ( void ) : void public send ( mixed $value ) : mixed public throw ( Exception $exception ) : void public valid ( void ) : bool public __wakeup ( void ) : void}生成器有什么用?

搞了半天不就是個迭代器嘛?搞這么麻煩干嘛,直接用迭代器或者在方法中直接返回一個數組不就好了嗎?沒錯,正常情況下真的沒有這么麻煩,但是如果是在數據量特別大的情況下,這個生成器就能發揮它的強大威力了。生成器最最強大的部分就在于,它不需要一個數組或者任何的數據結構來保存這一系列數據。每次迭代都是代碼執行到 yield 時動態返回的。因此,生成器能夠極大的節約內存。

// 內存占用測試$start_time = microtime(true);function test2($clear = false){ $arr = []; if($clear){$arr = null;return; } for ($i = 0; $i < 1000000; $i++) {$arr[] = $i + 1; } return $arr;}$array = test2();foreach ($array as $val) {}$end_time = microtime(true);echo 'time: ', bcsub($end_time, $start_time, 4), PHP_EOL;echo 'memory (byte): ', memory_get_usage(true), PHP_EOL;// time: 0.0513// memory (byte): 35655680$start_time = microtime(true);function test3(){ for ($i = 0; $i < 1000000; $i++) {yield $i + 1; }}$array = test3();foreach ($array as $val) {}$end_time = microtime(true);echo 'time: ', bcsub($end_time, $start_time, 4), PHP_EOL;echo 'memory (byte): ', memory_get_usage(true), PHP_EOL;// time: 0.0517// memory (byte): 2097152

上述代碼只是簡單的進行 1000000 個循環后獲取結果,不過也可以直觀地看出。使用生成器的版本僅僅消耗了 2M 的內存,而未使用生成器的版本則消耗了 35M 的內存,直接已經10多倍的差距了,而且越大的量差距超明顯。因此,有大神將生成器說成是PHP中最被低估了的一個特性。

生成器的應用

接下來我們來看看生成器的一些基本的應用方式。

返回空值以及中斷

生成器當然也可以返回空值,直接 yield; 不帶任何值就可以返回一個空值了。而在方法中直接使用 return; 也可以用來中斷生成器的繼續執行。下面的代碼我們在 i = 4; 的時候返回的是個空值,也就是不會輸出 5 (因為我們返回的是i=4;的時候返回的是個空值,也就是不會輸出5(因為我們返回的是i + 1 )。然后在 $i == 7 的時候使用 return; 中斷生成器的繼續執行,也就是循環最多只會輸出到 7 就結束了。

// 返回空值以及中斷function test4(){ for ($i = 0; $i < 10; $i++) {if ($i == 4) { yield; // 返回null值}if ($i == 7) { return; // 中斷生成器執行}yield $i + 1; }}foreach (test4() as $t) { echo $t, PHP_EOL;}// 1// 2// 3// 4// 5// 6// 7返回鍵值對形式

不要驚訝,生成器真的是可以返回鍵值對形式的可遍歷對象供 foreach 使用的,而且語法非常好記: yield key => value; 是不是和數組項的定義形式一模一樣,非常直觀好理解。

function test5(){ for ($i = 0; $i < 10; $i++) {yield ’key.’ . $i => $i + 1; }}foreach (test5() as $k=>$t) { echo $k . ’:’ . $t, PHP_EOL;}// key.0:1// key.1:2// key.2:3// key.3:4// key.4:5// key.5:6// key.6:7// key.7:8// key.8:9// key.9:10外部傳遞數據

我們可以通過 Generator::send 方法來向生成器中傳入一個值。傳入的這個值將會被當做生成器當前 yield 的返回值。然后我們根據這個值可以做一些判斷,比如根據外部條件中斷生成器的執行。

function test6(){ for ($i = 0; $i < 10; $i++) {// 正常獲取循環值,當外部send過來值后,yield獲取到的就是外部傳來的值了$data = (yield $i + 1);if($data == ’stop’){ return;} }}$t6 = test6();foreach($t6 as $t){ if($t == 3){$t6->send(’stop’); } echo $t, PHP_EOL;}// 1// 2// 3

上述代碼理解起來可能比較繞,但是注意記住注釋的那行話就行了(正常獲取循環值,當外部send過來值后,yield獲取到的就是外部傳來的值了)。另外,變量獲取 yield 的值,必須要用括號括起來。

yield from 語法

yield from 語法其實就是指的從另一個可迭代對象中一個一個的獲取數據并形成生成器返回。直接看代碼

function test7(){ yield from [1, 2, 3, 4]; yield from new ArrayIterator([5, 6]); yield from test1();}foreach (test7() as $t) { echo ’test7:’, $t, PHP_EOL;}// test7:1// test7:2// test7:3// test7:4// test7:5// test7:6// test7:1// test7:2// test7:3// test7:1000

在 test7() 方法中,我們使用 yield from 分別從普通數組、迭代器對象、另一個生成器中獲取數據并做為當前生成器的內容進行返回。

小驚喜生成器可以用count獲取數量嗎?

抱歉,生成器是不能用count來獲取它的數量的。

$c = count(test1()); // Warning: count(): Parameter must be an array or an object that implements Countable// echo $c, PHP_EOL;

使用 count 來獲取生成器的數量將直接報 Warning 警告。直接輸出將會一直顯示是 1 ,因為 count 的特性(強制轉換成數組都會顯示 1 )。

使用生產器來獲取斐波那契數列

// 利用生成器生成斐波那契數列function fibonacci($item){ $a = 0; $b = 1; for ($i = 0; $i < $item; $i++) {yield $a;$a = $b - $a;$b = $a + $b; }}$fibo = fibonacci(10);foreach ($fibo as $value) { echo '$valuen';}

這段代碼就不多解釋了,非常直觀的一段代碼了。

總結

生成器絕對是PHP中的一個隱藏的寶藏,不僅是對于內存節約來說,而且語法其實也非常的簡潔明了。我們不需要在方法內部再多定義一個數組去存儲返回值,直接 yield 一項一項的返回就可以了。在實際的項目中完全值得嘗試一把,但是嘗試完了別忘了和小伙伴們分享,大部分人可能真的沒有接觸過這個特性哦!!

測試代碼: github.com/zhangyue050…

以上就是PHP 生成器的使用詳解的詳細內容,更多關于PHP 生成器的資料請關注好吧啦網其它相關文章!

標簽: PHP
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
免费精品国产的网站免费观看| 亚洲三级网址| 久久这里只有| 国产剧情在线观看一区| 日本va欧美va瓶| 青草综合视频| 久久99蜜桃| 精品日本视频| 中文字幕在线看片| 亚洲va中文在线播放免费| а√天堂8资源在线| 精品一二三区| 人在线成免费视频| 久久九九电影| 国产综合色区在线观看| 久久精品电影| 午夜一区在线| 亚洲aa在线| 国产精品久一| 日韩在线综合| 日韩一级网站| 日韩中出av| 欧美aa在线视频| 中文字幕在线视频网站| 国内亚洲精品| 一区二区三区网站| 国产探花一区| 亚洲精品**中文毛片| 国内激情久久| 免费日本视频一区| 日韩精品1区2区3区| 麻豆久久久久久| 日韩精品久久久久久久电影99爱| 欧美日韩国产高清| 日韩精品成人在线观看| 精品三级av在线导航| 日本高清不卡一区二区三区视频| 亚洲精品99| 欧美在线精品一区| 欧美韩日一区| 亚洲欧美伊人| 日韩毛片一区| 成人在线黄色| 亚洲自拍另类| 日韩综合一区二区三区| 国产精品3区| 欧美手机在线| 日本天堂一区| 99久久99久久精品国产片果冰 | 久久精品91| 亚洲一区二区小说| 久久精品欧洲| 亚洲在线观看| 成人日韩av| 在线一区二区三区视频| 精品视频一区二区三区在线观看 | 美女视频黄久久| 女人天堂亚洲aⅴ在线观看| 日韩激情av在线| 热三久草你在线| 97久久精品| 五月天久久777| 久久精品资源| 欧美一区=区| 高清不卡一区| 亚洲综合色婷婷在线观看| 欧美国产日韩电影| 婷婷丁香综合| 国产成人精品福利| 亚洲毛片网站| 欧美日韩免费观看视频| 日韩av一二三| 国产综合欧美| 精品国产亚洲一区二区三区在线| 国产亚洲激情| 天堂√中文最新版在线| 日韩美女精品| 亚洲国产一区二区三区在线播放 | 久久九九国产| 久久亚洲精精品中文字幕| 男人操女人的视频在线观看欧美| 高清不卡亚洲| 国产激情久久| 美国欧美日韩国产在线播放| 日韩大片在线播放| 国产欧美一区二区色老头| 美女网站久久| 99精品视频在线| 国产91在线精品| 国产伦精品一区二区三区在线播放| 日韩一区二区久久| 91精品国产成人观看| 久久精品日韩欧美| 国产精品亚洲综合色区韩国| 一区二区国产在线| 亚洲一区日韩| 九九综合九九| 国产精品字幕| 精品精品99| 国产精品色在线网站| 日韩一区二区三区在线看| 亚洲综合丁香| 一区免费视频| 亚洲精品电影| 一级欧洲+日本+国产| 久久伦理在线| 欧美精品资源| 婷婷综合六月| 另类中文字幕国产精品| а√在线中文在线新版| 久久精品免费看| 国产精品magnet| 国产精品**亚洲精品| 日本a级不卡| 亚洲精品自拍| 亚州国产精品| 日韩高清电影免费| 日本麻豆一区二区三区视频| 日韩一区二区三区高清在线观看| 快she精品国产999| 视频一区欧美精品| 美女国产一区| 亚洲最大av| 深夜福利亚洲| 欧美午夜网站| 国产激情欧美| 精品久久久久中文字幕小说| 久久亚洲黄色| 高清精品久久| 91中文字幕精品永久在线| 国产传媒在线观看| 日韩理论片av| 亚洲香蕉网站| 国产精品腿扒开做爽爽爽挤奶网站| 日韩成人亚洲| 久久麻豆精品| 国产视频一区在线观看一区免费| 国产精品毛片在线看| 国产精品毛片在线看| 亚洲欧美久久| 日韩国产一二三区| 国产精品入口久久| 国产在线观看www| 亚洲国产专区校园欧美| 久久伦理在线| 免播放器亚洲| 日本午夜精品| 久久这里只有精品一区二区| 亚洲伊人av| 不卡一区综合视频| 亚洲精品伊人| 精品视频97| 欧美特黄一级| 日本久久一区| 老司机免费视频一区二区三区| 日韩1区2区| 欧美日韩国产高清| 色8久久久久| 麻豆精品国产91久久久久久| 国产成人久久精品麻豆二区| 91精品一区二区三区综合在线爱| 国产一级一区二区| 69精品国产久热在线观看| 精品黄色一级片| 性欧美69xoxoxoxo| 日韩国产欧美视频| 麻豆理论在线观看| 蜜桃伊人久久| 久久av偷拍| 好看的亚洲午夜视频在线| 日本伊人久久| 97精品国产| 蜜臀av一区二区三区| 美腿丝袜在线亚洲一区| 超碰超碰人人人人精品| 国产午夜精品一区二区三区欧美 | 在线亚洲成人| 久久不卡国产精品一区二区| 精精国产xxxx视频在线野外| 丝袜亚洲另类欧美| 美女视频黄 久久| 欧美另类专区| 欧美激情 亚洲a∨综合| 日韩视频免费| 久久中文字幕导航| 石原莉奈一区二区三区在线观看| 欧美一区网站| 五月天久久777| 久久免费福利| 在线观看一区| 欧美日韩免费观看视频| 婷婷精品在线观看| 久久精品影视| 国产精品久久久久av蜜臀 | 日韩大片在线| 日韩精品一区二区三区av| 精品国模一区二区三区| 久久精品凹凸全集| 女人天堂亚洲aⅴ在线观看| 久久激情av|