• php 迭代器与和生成器


    php有很多功能强大的接口,其中ArrayAccess 与 Iterator 的配合使用可以让对象与数组一样有着灵活的访问性。

    当然,用ArrayAccess 与 Iterator 配合可以用来对付数组,但还有一个更好的办法同则SPL 提供的ArrayIterator

    原因就是 :

    ArrayIterator implement ArrayAccess, SeekableIterator, Countable, Searializable {}

    而接下来要介绍的则是Iterator的更高一层用法。

    与Iterator有关的函数先记录下

    iterator_to_array() 把迭代器中的元素转换成数组

    IteratorAggregate::getIterator()   调用一个外部迭代器

    ArrayIterator

    Iteartor_count() 等等

    而php在使用Iterator接口则是迭代器模式的一种实现。在这里,其中的概念客户端(实现迭代过程)、迭代器、具体迭代器则会别对应于,foreach() , 继承于iterator接口的具体类和需要遍历的数组或集合。

    而生成器,则是建立在理解迭代器的基础之上。

    php中的生成器,可以叫做迭代生成器,因为它就是一个不可new的类,同时继承Iterator,且多了一个send() 与 生成器通信

    它的实现则是通过yield关键字,或语句,或表达式,其工作方式则是,使用yield的结构体就是一个生成生成器类,当执行到yield

    时,则中断该生成器,并存储其状态,当再次执行(foreach 或 while等循环结构) , 则会恢复其状态,并直到再次遇到yield

    <?php
    function gen() {
        $ret = (yield 'yield1');
        var_dump($ret);
        $ret = (yield 'yield2');
        var_dump($ret);
    }
     
    $gen = gen();
    var_dump($gen->current());    // output:string(6) "yield1" 当该生成器形成的时候
                                  //rewind()就已经隐式的执行,即生成就已经到第一个yield中断了
    var_dump($gen->send('ret1')); // output:string(4) "ret1"   (the first var_dump in gen)
                                  // 这时,send()则做了它该做的,恢复中断,把值(ret1)传入yield,并返回yield(ret1), 直到再遇到yield ,无则返回null
                                  // output:string(6) "yield2" (the var_dump of the ->send() return value)
                                 // 这时执行到$ret = (yields 'yield2'); 时则中磁芯,并把yield表达式的值返回,
    //此时为 yield2 ,若没有 后面的 ‘yield2’, 则会返回null
    var_dump($gen->send('ret2')); //output:string(6) "yield2" (the var_dump of the ->send() return value)
    // output:null
                       // 这时send()执行的时候 ,并没有下一个yield则返回的是null,而其恢复执行后在函数体内有一个var_dump(),所以会有output

    其实,由上面的实例可总结出两点 ,

    一是,初始化生成器时则已经到了一个yield,形成了中断,

    二是,send 的执行实际上是,先next() , 再vaild() , 不能过则return null, 通过则current() ,返回,若是yield 后没有“默认”($ret = (yield 'default');),

            则返回的是null,再进行中断,直至再次恢复。

    理解了它是如何工作的,则出现了一个实际的问题,它有什么用呢?

     生成器的高级使用出现在“在php中使用协程实现多任务调度”这一主题中,该主题偏难,而我对它的理解也只是到了简单的任务调度这一块

    而更高级的内容,再慢慢了解。

      为什么它能完成任务的调度呢?关于这一点可类比操作系统中的程序中断,在那里,中断的作用则就是为了任务调度。

          如何使用yield来完成任务调度,这一

  • 相关阅读:
    解决面试题的思路--5
    剑指offer例题分享--4
    剑指offer--3
    剑指offer--2
    【数据结构】5.2 二叉搜索树的创建查找以及插入操作
    【数据结构】5.1 顺序表的查找以及二分查找的实现
    【数据结构】4.1图的创建及DFS深度遍历(不完善)
    【密码学】RSA加密 kotlin实现方法(支持任意字节长度)
    【数据结构】3-2哈夫曼树的实现(数组实现)以及哈夫曼编码
    【密码学】公钥密码体制概述
  • 原文地址:https://www.cnblogs.com/z1298703836/p/4663171.html
Copyright © 2020-2023  润新知