PHP迭代器和生成器用法例項分析

2022-09-26 04:18:12 字數 2207 閱讀 4914

迭代器

迭代器實際是乙個實現了iterator的類,可以用foreach進行遍歷。

例如:<?php class sample implements iterator

public function current ()

public function key ()

public function next ()

public function rewind ()

public function send ( $value )

} public function valid ()

}$sample = new sample([1,2,3]);

foreach ($sample as $k =>$v)

輸出 valid current key next

可以看到foreach 是先呼叫valid判斷迭代器是否有效,然後再呼叫current獲取當前值,同時呼叫next移動key到指向下乙個值(輸出key是因為 $k=>$v的緣故)。

生成器讓我們先看一下官方文件

生成器提供了一種更容易的方法來實現簡單的物件迭代,相比較定義類實現 iterator 介面的方式,效能開銷和複雜性大大降低。

生成器允許你在 foreach **塊中寫**來迭代一組資料而不需要在記憶體中建立乙個陣列, 那會使你的記憶體達到上限,或者會佔據可觀的處理時間。

相反,你可以寫乙個生成器函式,就像乙個普通的自定義函式一樣, 和普通函式只返回一次不同的是, 生成器可以根據需要 yield 多次,以便生成需要迭代的值。

php 將會在每次需要值的時候呼叫生成器函式,並在產生乙個值之後儲存生成器的狀態,這樣它就可以在需要產生下乙個值的時候恢復呼叫狀態。

下面是php官方文件中的示例

<?php function gen_one_to_three()

}$generator = gen_one_to_three();

foreach ($generator as $value)

var_dump($generator); //實際上是generator物件

如上,若把3修改成10000,對於$generator實際上沒有區別,它只是儲存了乙個當前值(當然還有相關的內部狀態,這裡是為了簡化),並沒有產生10000個數。

從中可以看出生成器的優勢在於減少記憶體的使用,在需要時才生成對應的值。

檢視php文件,我們可以看到generator實際也是iterator的具體實現,yield呼叫時就是返回的generator物件。

那麼怎麼理解迭代器和生成器的關係呢?

其實,生成器是迭代器的實現+yield,產生了生成器物件。

我們也可以自己定義乙個類似yield的函式,如下:

function myyeild()

$generator = myyeild(1,2,3);

foreach ($generator as $value)

注意,我們的myyeild,是不能和php內建的yeild那麼使用的,因為yeild會儲存呼叫上下文,臨時離開,並沒有return。

這裡只是模擬一下。

既然yeild可以把普通的物件包裝成generator,那麼我們的iterator通過yeild也可以像generator一樣嗎?

答案有點悲傷,yeild是把傳入的值作為引數生成generator例項,它並不知道我們的iterator。不過這樣設計也是合理的,

以防我們自己的iterator不靠譜。

實際使用場合

可以結合游標,遍歷資料庫時,不需要一次程式設計客棧返回所有資料,而是每次取一行。

class alluser implements \iterator

//1 重置迭代器

public function rewind()

//2 驗證迭代器是否有資料

public function valid()

//3 獲取當前內容

public function current()

//4 移動key到下乙個

public function next()

//5 迭代器位置key

public function key() }

//實現迭代遍歷使用者表

$users = new alluser();

//可實時修改

foreach ($users as $user)

注意:可以在生成器的函式前加"&",可以使用引用。在函式裡直接return會終止生成器。

PHP5 5迭代生成器用法例項詳解

php5.5引入了迭代生成器的概念,迭代的概念早就在php有了,但是迭代生成器是php的乙個新特性,這跟python3中的迭代生成器類似,看看php5.5的迭代生成器如何定義。foreach xrange 1,1000000 as num 注意關鍵字 yield,正是這個yeild關鍵字構建了乙個迭...

python yield 生成器用法

總結 可以把send 看成是next 的公升級版。send 不僅能像next 一樣觸發生成器的乙個迭代,還能傳入乙個值給yield語句。看下面乙個列子 def func y 1 while true x yield y y 1 print 接收了x format x f func f是乙個初始化好的...

迭代器和生成器的用法

首先在了解解析式之前,我們先來看乙個列子 乙個列表,元素是0 9,列表中的每個值自增1,該如何實現 方法一 遍歷列表,對其元素進行加1操作後放到乙個新的列表中 1 lst 0,1,2,3,4,5,6,7,8,9 23 for index,i in enumerate lst 4 lst index ...