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来完成任务调度,这一
php 迭代器与和生成器的更多相关文章
- ES6中的迭代器(Iterator)和生成器(Generator)
前面的话 用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简 ...
- 迭代器&迭代对象&生成器
迭代器 & 迭代对象 & 生成器 包含__next__ 和 __iter__两个方法的对象为迭代器 __next__方法返回单个元素 __iter__方法返回迭代器本身 可迭代对象包含 ...
- python基础之迭代器协议和生成器(二)
一.什么是迭代器: 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器是一个可以记住遍历的位置的对象. 迭代器的 ...
- ES6中的迭代器(Iterator)和生成器(Generator)(一)
用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简化数据操作 ...
- Python基础(四)——迭代器/对象,生成器
首先廖雪峰网站写的内容就我目前初步学习来说,已经相当详实,知识点平铺直叙让人易接受,所以以下内容均作为一种摘记记录以及补充. 1. 列表生成器 主要目的是创建 list .多看例子就能清楚: #列表生 ...
- (转)python基础之迭代器协议和生成器(一)
一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- 迭代器 (Iterator) 和 生成器 (Generator)
其他章节请看: es6 快速入门 系列 迭代器 (Iterator) 和 生成器 (Generator) 试图解决的问题 let colors = ['red', 'blue', 'green', ' ...
- Python的迭代器(iterator)和生成器(constructor)
一.迭代器(iterator) 1.迭代器的概述 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器 ...
- Python之路:迭代器和yield生成器
一.迭代器 对于Python 列表的 for 循环,他的内部原理:查看下一个元素是否存在,如果存在,则取出,如果不存在,则报异常 StopIteration.(python内部对异常已处理) 使用迭代 ...
随机推荐
- C# Winform程序本地化应用
1. 创建一个WinForm应用程序 – “WindowsFormsLocalizationTest”. 2. 在主窗体属性栏里,把Localizable属性设置成”True”. 3. 添加两个But ...
- The port Command
The port Command help: port help selfupdate selfupdate: sudo port selfupdate search: port search tft ...
- 关于left join连接查询 两张表里有同名字段的问题
左连接查询在开发中很常用,但有个问题常常会遇到,两个表中有同名字段时,比如左右表都有一个id字段,会造成查询结果中左表的id值被右表的id值覆盖掉(大部分php框架都是这个效果),而且还不会报错,容易 ...
- centos出现磁盘坏掉,怎么修复和检测。
当dmesg的时候,出现下面的信息说明磁盘有问题 Info fld=0x139066d0 end_request: I/O error, dev sda, sector 328230608 Buffe ...
- PHP环境搭配
电脑上如果有apache,必须先卸载了先,如果有集成的环境,类似于apmserver,也必须先停止先.不然安装的时候,会出现修复和卸载选项,而不是典型安装跟用户自定义安装. apache安装目录 E: ...
- SQL Server 阻塞排除的 2 方法
背景知识: 是什么造成了阻塞? 从锁的观点来看.可访问对象前一定要对对象加锁不管你是读还是写,如果用户A以经持有对象,说明A以在对象上加锁,如果这时B 也想访问这个对象.它也要对对象加锁.重点来了如果 ...
- JQuery 的基本命令
调用jquery的格式 <script> $(document).ready(function() { }); </script> 笔记 1.现在让我们开始写第 ...
- Async 与 Await 关键字研究
1 Aynsc 和 Await 关键字的研究 在 .NET 4.0 以后,基于 Task 的异步编程模式大行其道,因其大大简化了异步编程所带来的大量代码工作而深受编程人员的欢迎,如果你曾 ...
- 在WPF中自定义你的绘制(五)
原文:在WPF中自定义你的绘制(五) 在WPF中自定义你的绘制(五) ...
- Poj 1269 Intersecting Lines_几何模板
#include <iostream> #include <math.h> #include <iomanip> #define eps 1e-8 #define ...