轻量级“集合”迭代器-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 ...
随机推荐
- 旺财速啃H5框架之Bootstrap(五)
在上一篇<<旺财速啃H5框架之Bootstrap(四)>>做了基本的框架,<<旺财速啃H5框架之Bootstrap(二)>>篇里也大体认识了bootst ...
- Centos6.5下编译安装mysql 5.6
一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server rpm -qa | grep mysql 有的话通过下面的命令来卸载掉 rpm -e mysql //普通删除模式 rpm -e ...
- Matlab 高脚杯模型切片
前言:此文为去年我替人做的一个课题,觉得比较简洁,图形也比较美观,因此放在博文里 数据源我放到了百度云盘高脚杯数据源 有兴趣的可以下载数据,跑程序试一下.也可以单独看看代码,看下实现过程. 主函数 % ...
- [C#] C# 知识回顾 - 特性 Attribute
C# 知识回顾 - 特性 Attribute [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5911289.html 目录 特性简介 使用特性 特性 ...
- 【Reading Note】算法读书杂记
1 排序 排序基本信息 稳定性:排序前大的数在排序后,大的数依然保持不变就是稳定排序,反之不稳定 内外排序:根据待排序的记录是否放在内存里面区分的.诸如:插入排序(直接插入&希尔).交换排序( ...
- ls: 无法访问/usr/sbin/smartctl: 没有那个文件或目录
环境:RHEL6.5 + Oracle 11.2.0.4 RAC 在安装RAC时,检查时缺少包 cvuqdisk-1.0.9-1,oracle提供脚本修复安装. 但在执行时报错: [root@orad ...
- jQuery幻灯片插件autoPic
原文地址:Jquery自定义幻灯片插件 插件效果图: 演示地址:autoPic项目地址:autoPic 欢迎批评指正!
- OpenLiveWriter代码插件
1.OpenLiveWriter安装 Windows Live Writer在2012年就停止了更新,Open Live Writer(以下简称OLW)是由Windows Live WriterWri ...
- JavaScript实现DOM对象选择器
目的: 根据传入的选择器类型选出第一个符合的DOM对象. ①可以通过id获取DOM对象,例如 $("#adom"); ②可以通过tagName获取DOM对象,例如 $(" ...
- Android Weekly Notes Issue #237
Android Weekly Issue #237 December 25th, 2016 Android Weekly Issue #237 这是本年的最后一篇issue, 感谢大家. 本期内容包括 ...