首頁  >  文章  >  後端開發  >  PHP生成器Generators的簡單解析

PHP生成器Generators的簡單解析

不言
不言原創
2018-08-04 09:28:461707瀏覽

這篇文章要跟大家介紹的內容是關於PHP生成器Generators的簡單解析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

什麼是生成器Generators

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

一個簡單的例子就是使用生成器來重新實作 range() 函數。標準的 range() 函數需要在記憶體中產生一個陣列包含每一個在它範圍內的值,然後傳回該陣列, 結果就是會產生多個很大的陣列。例如,呼叫 range(0, 10000) 將導致記憶體佔用超過 4 MB。

範例程式碼:

<?php
/**
 * Created by PhpStorm.
 * User: chenbotome@163.com
 * Date: 2018/7/30
 * Time: 上午11:29
 */
$start = xdebug_memory_usage();
$num = 10000;
function rangeWithGenerators($start, $limit, $step = 1) {
    if ($start < $limit) {
        if ($step <= 0) {
            throw new LogicException(&#39;Step must be +ve&#39;);
        }

        for ($i = $start; $i <= $limit; $i += $step) { 
        yield $i;
        }
         } else { 
         if ($step >= 0) {
            throw new LogicException('Step must be -ve');
        }

        for ($i = $start; $i >= $limit; $i += $step) {
            yield $i;
        }
    }
}
if ($argc === 1) {
    $iterate = rangeWithGenerators(0, $num, 1);
    foreach ($iterate as $value){
        echo $value . "\n";
    }
    //var_dump(iterator_to_array($iterate));
}
if ($argc === 2) {
    $test = range(0, $num, 1);
    foreach ($test as $value) {
        echo $value . "\n";
    }
}
$end = xdebug_memory_usage();

echo sprintf("内存消耗量%s\n", convert($end-$start));

function convert($size){
    $unit=array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

環境

  • PHP7.1

  • Xdebug

#執行指令

  • #php test.php 結果回傳:記憶體消耗量416 b

  • php test.php range 結果回傳:記憶體消耗量4 mb

測試結果論述

  • 透過程式碼的執行,比較除了PHP標準函數rang()和自訂函數rangeWithGenerators()之間的異同。實現了同樣的目的,卻消耗著不同的內存,生成器的優點顯而易見。

  • rangeWithGenerators()使用了生成器,而生成器的關鍵就是使用yield關鍵字,yield常見的使用涉及foreach和for兩個流程控制語句。 rangeWithGenerators()中for迴圈yield變數$i(yield可理解為生成-值,如同return可理解為返回-​​值)。

  • rangeWithGenerators()函數傳回的便是一個生成器Generators( 使用var_dump($iterate)檢視其型別 )。

  • 既然rangeWithGenerators()函數回傳的是生成器,我們可以用以下兩種方式來使用:

  1. ##foreach循環該Generators,本例中則使用此方法讀取Generators。

  2. PHP標準函數iterator_to_array(),該函數將Generators轉換為一個Array。

相關文章推薦:

PHP中json_encode的使用方法介紹

php如何使用curl接收POST位址即建立一個介面的方法

以上是PHP生成器Generators的簡單解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn