zoukankan      html  css  js  c++  java
  • Iterator 接口

    首先要从foreach说起,我们都知道对象,数组和对象可以被foreach语法遍历,数字和字符串却不行。
    其实除了数组和对象之外PHP内部还提供了一个 Iterator 接口,实现了Iterator接口的对象,也是可以被foreach语句遍历,当然跟普通对象的遍历就很不一样了。 以下面的代码为例:
    class Number implements Iterator{
      protected $key;
      protected $val;
      protected $count;
    
      public function __construct(int $count){
        $this->count = $count;
      }
    
      public function rewind(){
        $this->key = 0;
        $this->val = 0;
      }
    
      public function next(){
      $this->key += 1;
      $this->val += 2;
      }
    
      public function current(){
        return $this->val;
      }
    
      public function key(){
      return $this->key + 1;
      }
    
      public function valid(){
        return $this->key < $this->count;
      }
    }
    
    
    foreach (new Number(5) as $key => $value){
      echo "{$key} - {$value}
    ";
    }
    

    这个例子将输出

    1 - 0
    2 - 2
    3 - 4
    4 - 6
    5 - 8

    关于上面的number对象,被遍历的过程。如果是初学者,可能会出现有点懵的情况。为了深入的了解Number对象被遍历的时候内部是怎么工作的,我将代码改了一下,将接口内的每个方法都尽心输出,借此来窥探一下遍历时对象内部方法的的执行情况。

    class Number implements Iterator{  
            protected $i = 1;
            protected $key;
            protected $val;
            protected $count; 
            public function __construct(int $count){
                $this->count = $count;
                echo "第{$this->i}步:对象初始化.
    ";
                $this->i++;
            }
            public function rewind(){
                $this->key = 0;
                $this->val = 0;
                echo "第{$this->i}步:rewind()被调用.
    ";
                $this->i++;
            }
            public function next(){
                $this->key += 1;
                $this->val += 2;
                echo "第{$this->i}步:next()被调用.
    ";
                $this->i++;
            }
            public function current(){
                echo "第{$this->i}步:current()被调用.
    ";
                $this->i++;
                return $this->val;
            }
            public function key(){
                echo "第{$this->i}步:key()被调用.
    ";
                $this->i++;
                return $this->key;
            }
            public function valid(){
                echo "第{$this->i}步:valid()被调用.
    ";
                $this->i++;
                return $this->key < $this->count;
            }
        }
    
        $number = new Number(5);
        echo "start...
    ";
        foreach ($number as $key => $value){
            echo "{$key} - {$value}
    ";
        }
        echo "...end...
    ";

    以上代码输出如下

    第1步:对象初始化.
    start...
    第2步:rewind()被调用.
    第3步:valid()被调用.
    第4步:current()被调用.
    第5步:key()被调用.
    0 - 0
    第6步:next()被调用.
    第7步:valid()被调用.
    第8步:current()被调用.
    第9步:key()被调用.
    1 - 2
    第10步:next()被调用.
    第11步:valid()被调用.
    第12步:current()被调用.
    第13步:key()被调用.
    2 - 4
    第14步:next()被调用.
    第15步:valid()被调用.
    第16步:current()被调用.
    第17步:key()被调用.
    3 - 6
    第18步:next()被调用.
    第19步:valid()被调用.
    第20步:current()被调用.
    第21步:key()被调用.
    4 - 8
    第22步:next()被调用.
    第23步:valid()被调用.
    ...end...

    看到这里,我相信大家对Iterator接口已经有一定认识了。

    会发现当对象被foreach的时候,内部的valid,current,key方法会依次被调用,其返回值便是foreach语句的key和value。

    循环的终止条件则根据valid方法的返回而定。

    如果返回的是true则继续循环,如果是false则终止整个循环,结束遍历。

    当一次循环体结束之后,将调用next进行下一次的循环直到valid返回false。

    而rewind方法则是在整个循环开始前被调用,这样保证了我们多次遍历得到的结果都是一致的。

  • 相关阅读:
    angular的路由例子
    angular自定义module
    docker配置phpadmin需要注意的地方
    linux下钉钉,微信
    debian shell脚本关联
    debian下安装带界面的qemu
    ros的一些设置
    新闻排重方案设计
    细解动态规划(一)
    漫画谈-微积分(二)
  • 原文地址:https://www.cnblogs.com/sgm4231/p/9778134.html
Copyright © 2011-2022 走看看