php 迭代器與和生成器

2022-08-19 11:15:09 字數 2028 閱讀 7313

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()

$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來完成任務排程,這一

迭代器與生成器

可迭代物件 可以直接作用於for迴圈的物件 統稱為可迭代物件 返回迭代器的物件 即iterable。一是集合資料型別,如list tuple dict set str等 二是generator,包括生成器和帶yield的generator function。容器 簡單來說 容器是一系列元素的集合 容...

生成器與迭代器

迭代是python最強大的功能之一,是訪問集合元素的一種方式。迭代器是乙個可以記住遍歷的位置的物件。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。迭代器有兩個基本的方法 iter 和 next 字串,列表或元組物件都可用於建立迭代器 list 1,2,3,...

生成器與迭代器

通過列表推導式,可以直接建立乙個列表,但是收到記憶體限制,列表容量肯定是有限的而且,建立乙個包含100萬個元素的列表,占用很大的儲存空間。如果我們僅僅需要訪問前面幾個元素,後面 後面元素的占用儲存空間就被浪費 所以,如果列表元素可以按照某種演算法算出來,那我們就可以再迴圈當中不斷地推導它,生成元素,...