1. 程式人生 > >php 叠代器與和生成器

php 叠代器與和生成器

表達 fun acc 調用 轉換 叠代 需要 函數 進行

php有很多功能強大的接口,其中ArrayAccess 與 Iterator 的配合使用可以讓對象與數組一樣有著靈活的訪問性。

當然,用ArrayAccess 與 Iterator 配合可以用來對付數組,但還有一個更好的辦法同則SPL 提供的ArrayIterator

原因就是 :

ArrayIterator implement ArrayAccess, SeekableIterator, Countable, Searializable {}

而接下來要介紹的則是Iterator的更高一層用法。

與Iterator有關的函數先記錄下

iterator_to_array() 把叠代器中的元素轉換成數組

IteratorAggregate::getIterator() 調用一個外部叠代器

ArrayIterator

Iteartor_count() 等等

而php在使用Iterator接口則是叠代器模式的一種實現。在這裏,其中的概念客戶端(實現叠代過程)、叠代器、具體叠代器則會別對應於,foreach() , 繼承於iterator接口的具體類和需要遍歷的數組或集合。

而生成器,則是建立在理解叠代器的基礎之上。

php中的生成器,可以叫做叠代生成器,因為它就是一個不可new的類,同時繼承Iterator,且多了一個send() 與 生成器通信

它的實現則是通過yield關鍵字,或語句,或表達式,其工作方式則是,使用yield的結構體就是一個生成生成器類,當執行到yield

時,則中斷該生成器,並存儲其狀態,當再次執行(foreach 或 while等循環結構) , 則會恢復其狀態,並直到再次遇到yield

技術分享
<?php
function gen() {
    $ret = (yield ‘yield1‘);
    var_dump($ret);
    $ret = (yield ‘yield2‘);
    var_dump($ret);
}
 
$gen = gen();
var_dump($gen->current());    // output:string(6) "yield1" 當該生成器形成的時候
                              //rewind()就已經隱式的執行,即生成就已經到第一個yield中斷了
var_dump($gen->send(‘ret1‘)); // output:string(4) "ret1"   (the first var_dump in gen)
                              // 這時,send()則做了它該做的,恢復中斷,把值(ret1)傳入yield,並返回yield(ret1), 直到再遇到yield ,無則返回null
                              // output:string(6) "yield2" (the var_dump of the ->send() return value)
                             // 這時執行到$ret = (yields ‘yield2‘); 時則中磁芯,並把yield表達式的值返回,
//此時為 yield2 ,若沒有 後面的 ‘yield2’, 則會返回null var_dump($gen->send(‘ret2‘)); //output:string(6) "yield2" (the var_dump of the ->send() return value)
// output:null
                   // 這時send()執行的時候 ,並沒有下一個yield則返回的是null,而其恢復執行後在函數體內有一個var_dump(),所以會有output
技術分享

其實,由上面的實例可總結出兩點 ,

一是,初始化生成器時則已經到了一個yield,形成了中斷,

二是,send 的執行實際上是,先next() , 再vaild() , 不能過則return null, 通過則current() ,返回,若是yield 後沒有“默認”($ret = (yield ‘default‘);),

則返回的是null,再進行中斷,直至再次恢復。

理解了它是如何工作的,則出現了一個實際的問題,它有什麽用呢?

生成器的高級使用出現在“在php中使用協程實現多任務調度”這一主題中,該主題偏難,而我對它的理解也只是到了簡單的任務調度這一塊

而更高級的內容,再慢慢了解。

  為什麽它能完成任務的調度呢?關於這一點可類比操作系統中的程序中斷,在那裏,中斷的作用則就是為了任務調度。

如何使用yield來完成任務調度,這一

php 叠代器與和生成器