轻量级“集合”迭代器-Generator
Generator是PHP 5.5加入的新语言特性。但是,它似乎并没有被很多PHP开发者广泛采用。因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下Generator究竟为我们解决什么问题。
一千万个整数的数组
如果我们要“创建一个指定元素个数的数组”,怎么做呢?我们可能会不加思索的写下下面的代码:
function makeRange($range) {
$data = [];
for ($i = 0; $i < $range; $i++) {
$data[] = $i;
}
return $data;
}
然后,在我们的开发环境里,分别创建1万个,10万个,100万个元素的数组,一切看起来都如我们想象。
makeRange(10000);
makeRange(100000);
makeRange(1000000);
但是,当我们创建一个包涵1千万个整数的数组时,情况就不一样了,系统没有那么多内存分配给我们:
makeRange(10000000);

把PHP Generator请出来帮忙
定义PHP generator很简单,看上去就像定义一个函数一样:
function makeRangeByGenerator($range) {
for ($i = 0; $i < $range; $i++) {
yield $i;
}
}
只是,makeRangeByGenerator没有返回值,也没有把整个数组创建在内存里,而只是通过关键字yield,标记了每次循环应该生成的值。接下来,我们可以像访问一个普通集合一样使用generator:
foreach ($makeRangeByGenerator(100) as $i) {
echo $i.'<br>';
}

现在重新执行我们的PHP文件,就不会再报错了。并且,我们可以在页面上,看到generator生成的值。这就是generator的典型应用场景,简单来说:Generator就是一个轻量级迭代器,它可以自动的记住每一次被调用时的状态,并返回给我们正确的值。
PHP 7做了哪些改进?
了解了generator的基本用法之后,我们就可以看一下PHP 7对它做了哪些改进了。
PHP 7允许我们给generator加入返回值,就像我们定义函数的返回值一样:
function makeRangeByGenerator($range) {
for ($i = 0; $i < $range; $i++) {
yield $i;
} return "Finish yielding";}
迭代完generator的所有元素时,我们就可以通过getReturn()方法,来读取generator的返回值:
$gen = makeRangeByGenerator(100);
foreach ($gen as $i) {
echo $i.'<br>';
}
echo $gen->getReturn();

*“我们必须在所有迭代完generator所有值之后,才能读取generator的返回值,否则PHP会报错。”
——最佳实践*

PHP 7对generator的第二个改进就是允许嵌套。例如:
function outer() {
yield "PHP 7 ";
yield "is one of ";
yield "the best ";
yield from inner();
}
function inner() {
yield "programming languages in the world";
}
我们使用关键字from引入一个新的generator,当我们遍历outer generator时,我们就会发现,它自动生成了inner generator的值:
foreach(outer() as $str) {
echo $str;
}
PHP 7对generator的第二个改进就是允许嵌套。例如:
function outer() {
yield "PHP 7 ";
yield "is one of ";
yield "the best ";
yield from inner();
}
function inner() {
yield "programming languages in the world";
}
我们使用关键字from引入一个新的generator,当我们遍历outer generator时,我们就会发现,它自动生成了inner generator的值:
foreach(outer() as $str) {
echo $str;
}

这就是关于PHP generator的全部内容。简单来说,generator就是一个轻量级的,可以记住自身状态的“集合”迭代器。如果你之前还不了解它,现在是时候考虑下它在哪些地方可以帮助到你了。
了解更多优质IT技术,拓展阅读视野,欢迎大家访问我们的合作伙伴Segmentfault
轻量级“集合”迭代器-Generator的更多相关文章
- 上手并过渡到PHP7(5)——轻量级“集合”迭代器-Generator
轻量级“集合”迭代器-Generator泊学视频链接泊阅文档链接Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Gener ...
- 集合迭代器快速失败行为及CopyOnWriteArrayList
以下内容基于jdk1.7.0_79源码: 什么是集合迭代器快速失败行为 以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入.移除...),而另一个线程 ...
- Java基础知识强化之集合框架笔记09:Collection集合迭代器使用的问题探讨
1.Collection集合迭代器使用的问题探讨: (1)问题1:能用while循环写这个程序,我能不能用for循环呢? 可以使用for循环替代. (2)问题2:不要 ...
- Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案
1. 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. ConcurrentModi ...
- -1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器
集合又称之为容器存储对象的一种方式 •数组虽然也可以存储对象,但长度是固定的:显然需要可变长度的容器 集合和数组的区别? A:长度区别 ...
- java集合迭代器
一.Java中有一个设计模式是迭代器模式 1.迭代器模式定义迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 2.迭代器模式概述Java集合框 ...
- Java中的集合迭代器
集合的迭代器 任何集合都有迭代器. 任何集合类,都必须能以某种方式存取元素,否则这个集合容器就没有任何意义. 迭代器,也是一种模式(也叫迭代器模式).在java中它是一个对象,其目的是遍历并选中其中的 ...
- Java集合迭代器 Iterator分析
简介 迭代器是遍历容器的一种常用方法,它屏蔽了容器的实现细节,无需暴露数据结构内部,就可以对容器进行遍历,迭代器本身也是一种设计模式,迭代是一种特殊的遍历方式. Iterator 在java中,迭代器 ...
- Day 4:集合——迭代器与List接口
Collection-迭代方法 1.toArray() 返回Object类型数据,接收也需要Object对象! Object[] toArray(); Collection c = new Arra ...
随机推荐
- 创建 OVS flat network - 每天5分钟玩转 OpenStack(134)
上一节完成了 flat 的配置工作,今天创建 OVS flat network.Admin -> Networks,点击 "Create Network" 按钮. 显示创建页 ...
- windows环境下sublime的nodejs插件详细安装图解
前面的话 搜索了好多文档后,才成功地安装了sublime text3的nodejs插件.为了存档,也为了方便有同样需求的朋友,将其安装过程详细记录如下 安装nodejs 虽然nodejs官网提供了 ...
- 卡片抽奖插件 CardShow
这个小项目(卡片秀)是一个卡片抽奖特效插件,用开源项目这样的词语让我多少有些羞愧,毕竟作为一个涉世未深的小伙子,用项目的标准衡量还有很大差距.不过该案例采用 jQuery 插件方式编写,提供配置参数并 ...
- mybatis_开发篇
一.使用mybatis的动态代理方式开发 需求:这里以crm系统中分页条件查询所有的客户信息的功能为例? 1.创建工程 2.引入所需的jar包 3.引入日志文件.数据库连接参数的配置文件等 4.创建m ...
- 开发者最爱的Firebug停止更新和维护
近日,Firebug团队在其官网上宣布,Firebug将不再继续开发和维护,并邀请大家使用Firefox的内置开发工具. Firebug最初是2006年1月由Joe Hewitt编写, ...
- mysql查询性能优化
mysql查询过程: 客户端发送查询请求. 服务器检查查询缓存,如果命中缓存,则返回结果,否则,继续执行. 服务器进行sql解析,预处理,再由优化器生成执行计划. Mysql调用存储引擎API执行优化 ...
- 项目自动化建构工具gradle 入门1——输出helloWorld
先来一个简单的例子,4个步骤: 1.进入D:\work\gradle\java 目录 ,您电脑没这目录? 那辛苦自己一级一级建立起来吧 新建文件build.gradle,文件内容是: apply p ...
- MyBatis3.2从入门到精通第一章
第一章一.引言mybatis是一个持久层框架,是apache下的顶级项目.mybatis托管到goolecode下,再后来托管到github下.(百度百科有解释)二.概述mybatis让程序将主要精力 ...
- qt5中信号和槽的新语法
qt5中的连接 有下列几种方式可以连接到信号上 旧语法 qt5将继续支持旧的语法去连接,在QObject对象上定义信号和槽函数,及任何继承QObjec的对象(包含QWidget). connect(s ...
- [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店
一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这 ...