生成器 PHP的生成器yield 原創

2021-09-30 13:45:59 字數 4197 閱讀 6784

在php 5.5中,php多了乙個新的特性,那就是生成器(generator)。生成器提供了一種更簡單的方法來實現簡單的物件迭代。

下面的manual的引用:

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

生成器允許你在 foreach **塊中寫**來迭代一組資料而不需要在記憶體中建立乙個陣列, 那會使你的記憶體達到上限,或者會佔據可觀的處理時間。相反,你可以寫乙個生成器函式,就像乙個普通的自定義函式一樣, 和普通函式只返回一次不同的是, 生成器可以根據需要 yield 多次,以便生成需要迭代的值。

乙個簡單的例子就是使用生成器來重新實現 range() 函式。 標準的 range() 函式需要在記憶體中生成乙個陣列包含每乙個在它範圍內的值,然後返回該陣列, 結果就是會產生多個很大的陣列。 比如,呼叫 range(0, 1000000) 將導致記憶體占用超過 100 mb。

做為一種替代方法, 我們可以實現乙個 xrange() 生成器, 只需要足夠的記憶體來建立 iterator 物件並在內部跟蹤生成器的當前狀態,這樣只需要不到1k位元組的記憶體。

下面的**可以將range實現為生成器:

<?

php

/**

* created by phpstorm.

* user: administrator

* date: 2017/7/10

* time: 11:55

*/

/**

* @param $start

* @param $limit

* @param int $step

* @return generator

*/

function

xrange($start, $limit, $step

=1)

for ($i

=$start; $i

<=

$limit; $i

+=$step)

} else

for ($i

=$start; $i

>=

$limit; $i

+=$step)

}

}

/**

* @param $start

* @param $limit

* @param int $step

* @return array

*/

function

yrange($start, $limit, $step

=1)

for ($i

=$start; $i

<=

$limit; $i

+=$step)

} else

for ($i

=$start; $i

>=

$limit; $i

+=$step)

}

return

$res;

}

echo

'single digit odd numbers from range(): ';

foreach (range(1, 9, 2) as

$number)

echo

"\n";

var_dump(xrange(1, 9, 2));

echo

'single digit odd numbers from xrange(): ';

foreach (xrange(1, 9, 2) as

$number)

echo

"\n";

echo

'single digit odd numbers from yrange(): ';

foreach (yrange(1, 9, 2) as

$number)

執行:

single digit odd numbers from range():  1 3 5 7 9

c:\laragon\www\php_book\test_yield.php:71:

class generator#1 (0)

single digit odd numbers from xrange(): 1 3 5 7 9

single digit odd numbers from yrange(): 1 3 5 7 9

其中的yrange其實也是實現了range的功能,寫上去只是為了和xrange對比而已。而var_dump出來只是提示是個generator類而已,並沒有把值列印出來,猜想應該是只有用foreach進行遍歷的時候才會去列印。

乙個生成器函式看起來像乙個普通的函式,不同的是普通函式返回乙個值,而乙個生成器可以yield生成許多它所需要的值。

當乙個生成器被呼叫的時候,它返回乙個可以被遍歷的物件.當你遍歷這個物件的時候(例如通過乙個foreach迴圈),php 將會在每次需要值的時候呼叫生成器函式,並在產生乙個值之後儲存生成器的狀態,這樣它就可以在需要產生下乙個值的時候恢復呼叫狀態。

一旦不再需要產生更多的值,生成器函式可以簡單退出,而呼叫生成器的**還可以繼續執行,就像乙個陣列已經被遍歷完了。

生成器函式的核心是yield關鍵字。它最簡單的呼叫形式看起來像乙個return申明,不同之處在於普通return會返回值並終止函式的執行,而yield會返回乙個值給迴圈呼叫此生成器的**並且只是暫停執行生成器函式。 

注意:生成器中是無法再生成器函式中返回值的。

以下是乙個簡單的生成值的例子:

<?

php

function

gen_one_to_three()

}

$generator

=gen_one_to_three();

foreach ($generator

as$value)

輸出:

1

23

再來看乙個例子:

<?

php

function

generator()

};

foreach (generator() as

$value)

執行:

123

456

php生成器 yield 轉

文件介紹說道 生成器函式的核心是yield關鍵字。它最簡單的呼叫形式看起來像乙個return申明,不同之處在於普通return會返回值並終止函式的執行,而yield會返回乙個值給迴圈呼叫此生成器的 並且只是暫停執行生成器函式。說了這麼多到底是個東西呢,只有自己親自動手寫 才知道。1 首先看下我們常用...

generator生成器與yield

普通函式 一路執行到底 generator函式 可以暫停執行 yield是什麼 yield是es6的新關鍵字,使生成器函式執行暫停,yield關鍵字後面的表示式的值返回給生成器的呼叫者。它可以被認為是乙個基於生成器的版本的return關鍵字。yield關鍵字實際返回乙個iteratorresult ...

Python之生成器(yield)

這裡是一段防爬蟲文字,請讀者忽略。本文原創首發於csdn,作者idys 部落格首頁 生成器函式 迭代器一定是可迭代物件,可迭代物件不一定是迭代器 def inc for i in range 5 yield i print type inc print type inc x inc print ty...