PHP的迭代器和生成器

一.迭代器

分析:想一下,若是把集合對象和對集合對象的操做放在一塊兒,當咱們想換一種方式遍歷集合對象中元素時,就須要修改集合對象了,違背「單一職責原則」,而迭代器模式將數據結構和數據結構的算法分離開,二者可獨立發展。php

優勢:算法

  1. 支持多種遍歷方式。好比有序列表,咱們根據須要提供正序遍歷、倒序遍歷兩種迭代器。用戶只須要獲得咱們的迭代器,就能夠對集合執行遍歷操做
  2. 簡化了聚合類。因爲引入了迭代器,原有的集合對象不須要自行遍歷集合元素了
  3. 增長新的聚合類和迭代器類很方便,兩個維度上可各自獨立變化
  4. 爲不一樣的集合結構提供一個統一的接口,從而支持一樣的算法在不一樣的集合結構上操做

缺點:數組

  1. 迭代器模式將存儲數據和遍歷數據的職責分離增長新的集合對象時須要增長對應的迭代器類,類的個數成對增長,在必定程度上增長系統複雜

具體接口:數據結構

Iterator extends Traversable {
   /* 方法 */
   abstract public mixed current ( void )
   abstract public scalar key ( void )
   abstract public void next ( void )
   abstract public void rewind ( void )
   abstract public bool valid ( void )
}

簡單的foreach迭代器實現函數

<?php
    class myIterator implements Iterator {
        private $position = 0;
        private $array = array(
            "firstelement",
            "secondelement",
            "lastelement",
        );  
    
        public function __construct() {
            $this->position = 0;
        }
    
        function rewind() {
            var_dump(__METHOD__);
            $this->position = 0;
        }
    
        function current() {
            var_dump(__METHOD__);
            return $this->array[$this->position];
        }
    
        function key() {
            var_dump(__METHOD__);
            return $this->position;
        }
    
        function next() {
            var_dump(__METHOD__);
            ++$this->position;
        }
    
        function valid() {
            var_dump(__METHOD__);
            return isset($this->array[$this->position]);
        }
    }
    
    $it = new myIterator;
    
    foreach($it as $key => $value) {
        var_dump($key, $value);
        echo "\n";
    }
?>

二.生成器

PHP生成器(generator)是PHP5.5.0引入的功能,與標準的PHP迭代器不一樣,PHP生成器不要求類實現Iterator接口,從而減輕了類的負擔,生成器會根據需求計算併產出要迭代的值,這對性能有重大的影響試想一下假如標準的PHP迭代器常常在內存中執行迭代操做者要預先計算出數據集性能低下;若是要使用特定的的方式對計算大量數據,對性能的影響更甚。此時咱們能夠使用生成器,即時計算產出後續值不佔用寶貴的內存資源。
優勢:性能

  1. 佔用內存少對,性能好。每次產出一個值以後,生成器的內部狀態都會停頓;當生成器請求下一個值時,內部狀態又會恢復。生成器的內部一直在停頓和恢復之間切換,直到循環完成或停頓位置

缺點:this

  1. PHP生成器不能知足全部迭代器的需求,由於若是不查詢,生成器永遠不知道下一個要迭代的值是什麼,在生成器中沒法後退或前進。
  2. 生成器仍是一次性的,沒法屢次迭代同一個生成器,不過,若是須要,能夠重建或克隆生成器。

 
建立生成器:scala

  1. 由於生成器就是PHP函數,生成器就是在函數中使用yield關鍵字。與普通的PHP函數不一樣的是,生產器從不返回值,只產出值。
<?php
        function myGenerator(){    
               yield 'a';    
               yield 'b';    
               yield 'c';
        }
  1. 調用生成器函數時,PHP會返回一個屬於Generator類的對象。
    這個對象能夠使用foreach()函數迭代。每次迭代,PHP會要求Generator實例計算並提供下一個要迭代的值
<?php
        function makeRange($length){    
               for($i = 0; $i<$length; $i++){        
                      yield $i;       
               }
        } 
        foreach(makeRange(1000000) as $i){    
               echo $i,PHP_EOL;
        }

如上所示:
當$length 很大時(上百萬),並且你同時沒有使用生成器的話,那麼就要預先爲一個由一百萬上一千五個整數組成的數組分配內存。而PHP生成器能實現相同的操做,不過一次只會爲一個整數分配內存code

相關文章
相關標籤/搜索