zoukankan      html  css  js  c++  java
  • 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来完成任务调度,这一

  • 相关阅读:
    Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor
    Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
    IdentityServer4 And AspNetCore.Identity Get AccessToken 问题
    Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
    Java Spring Boot VS .NetCore (七) 配置文件
    Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
    Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
    Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
    Java Spring Boot VS .NetCore (三)Ioc容器处理
    Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
  • 原文地址:https://www.cnblogs.com/zhangyingai/p/7096321.html
Copyright © 2011-2022 走看看