寫在前面
這篇文章,要和大家探討的是 PHP yield 在 生成器用法,不帶 foreach
,for
, while
循環的那種。就討論 yield
將一個函數變成為生成器的用法。
關于
yield
特性,是在開發PHP5
時被提上日程,PHP5.5
版本正式加入。
關于yield
的使用,我看到大部分文章都停留在,使用yield
如何在foreach
中穿出數據,今天想給大家講講 生成器 所有語法。
相關學習推薦:PHP編程從入門到精通
官網講解
生成器允許你在 foreach
代碼塊中寫代碼來迭代一組數據而不需要在內存中創建一個數組, 那會使你的內存達到上限,或者會占據可觀的處理時間。相反,你可以寫一個生成器函數,就像一個普通的自定義函數一樣, 和普通函數只返回一次不同的是, 生成器可以根據需要 yield
多次,以便生成需要迭代的值。
看了下官網對他講解:php.net 生成器語法 . 每個字都認識,但似乎還是體會到它講的內涵。官網我們主要看兩部分內容:
-
yield
的語法。 -
代碼例子。
先說語法, yield 的左邊是一個賦值語句,右邊可以是值(也可是表達式) 。而yield 會先執行右邊的表達式,并把值$value送到生成器外面。當生成器收到值后,會執行yield左邊的語句,賦值給$data.
<?phpfunction func(){ $data = (yield [$express]);}
語法就這樣,估計大家還是有些懵,那就看看官網下面代碼例子吧,我看里面例子參差不齊。
注意yield 外面包的這一層括號,如果是在php5.5,右側$express的優先級是判斷,可能會比左側$data的賦值語句低的。所以在php5用yield,yield 右邊是可運行表達式,左側需要接受返回并賦值,那么這個括號是有必要的。在php7不會有這個問題。
通過例子來了解它
不論是學 人類語言,計算機語言,都是模仿開始
對于一個用人類語言來描述,都不那么明晰時,所以那就通過例子告訴你它能做什么,不能做什么。
相關代碼,我放到gitee了,希望你能復制到你本地運行下,親自運行感受下,有助于了理解接下來的內容。
git clone gitee.com/xupaul/PHP-generator-yie…
怎樣才能產生 Generator
先定義一個函數,在函數內 寫個 yield 關鍵詞,將這個函數調用賦值給一個變量。一個生成器就產生了。
代碼 /php-yield-test/yieldFunctions.php 是生成器按照不同語法組合定義了多個生成器。
測試代碼 /php-yield-test/whatIsGenerator.php,用來檢查哪些函數能構成生成器,哪些不能。運行結果如下
- 函數內必須有
yield
關鍵詞,函數可以是全劇函數,或者類的方法。 - 哪怕
yield
肯定不會被執行,也會產生生成器。見:yield_func4 - 光禿禿 的
yield
關鍵詞就行(不向外送出,不處理外面的輸入)。見: yield_func2 - 函數內使用 生成器 并不能讓自己也成為生成器,見:yield_func5
- eval函數中直接運行
yield
會報錯, 見:yield_func11
是的,函數內有沒有foreach,while,for 語句都不是關鍵,關鍵是 yield. 生成器的類型判斷用
$gen instanceof Generator
生成器的函數
Generator 對象是從 generators返回的.
Generator 對象不能通過 new 實例化.
- Generator::current — 返回當前產生的值
- Generator::key — 返回當前產生的鍵
- Generator::next — 生成器繼續執行
- Generator::rewind — 重置迭代器
- Generator::send — 向生成器中傳入一個值
- Generator::throw — 向生成器中拋入一個異常
- Generator::valid — 檢查迭代器是否被關閉
- Generator::__wakeup — 序列化回調
- Gengerator::getReturn – Get the return value of a generator
摘自 php.net generator
看著以上方法,是不想起了
Iterator
, 他們的確很像。同時注意,官網zh語言版本的文檔沒有索引方法getReturn
,訪問也是404。文檔以en版為準,ch做參考。