PHP中的 Iterator 与 Generator
在讲解生成器之前先介绍一下迭代器:
在 PHP 中,通常情况下遍历数组使用 foreach 来遍历。
如果我们要想让一个对象可以遍历呢?
PHP 为我们提供了 Iterator 接口,只要实现了这个接口,这个对象就可以通过 foreach 来迭代。
例子如下:
class myIterator implements Iterator {
private $index = 0;
private $data = '';
public function __construct($data) {
$this->index = 0;
$this->data = $data;
}
function rewind() {
$this->index = 0;
}
function current() {
return $this->data[$this->index];
}
function key() {
return $this->index;
}
function next() {
++$this->index;
}
function valid() {
return isset($this->data[$this->index]);
}
}
$it = new myIterator(array(
"hello",
"php",
"iterator",
));
foreach($it as $key => $value) {
echo "$key : $value<br>";
}
我们通过foreach遍历 $it 时,PHP 会自己依次调用:
rewind() 重置到第一个元素
valid() 检查当前位置是否有效
current() 返回当前元素
key() 返回当前元素的键
next() 指向下一个元素
生成器是 PHP 5.5 引入的新特性,但是目前貌似很少人用到它。
下面试 PHP 官方文档上对生成器的解释:
生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。
生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。
为了体现生成器的有点,下面我们定义一个函数来进行比较:
function func1()
{
foreach (range(0, 1000000) as $value){
echo $value;
}
}
func1();
// ( ! ) Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 402653192 bytes) in xxx.php on line 5
因为创建如此大的数组到内存中进行迭代,则 PHP 直接提示超出了单个进程的内存限制。
下面我们换做生成器的方式来处理:
function func1()
{
foreach (range(0, 1000000) as $value){
yield $value;
}
}
var_dump(func1()); // object(Generator)[1]
foreach (func1() as $value){
echo $value;
}
可以看到我们调用 func1() 返回了一个 Generator 对象,这个对象可以使用 foreach 迭代,每次迭代,PHP 会要求 Generator 实例计算并提供下一个要迭代的值。生成器的优雅体现在每次产出一个值之后,生成器的内部状态都会停顿;向生成器请求下一个值时,内部状态又会恢复。生成器内部的状态会一直在停顿和恢复之间切换,直到抵达函数定义体的末尾或遇到空的return语句为止。
参考链接:
https://laravelacademy.org/po...
http://php.net/manual/zh/lang...
原文地址:https://segmentfault.com/a/1190000016475883
PHP中的 Iterator 与 Generator的更多相关文章
- [Python学习]Iterator 和 Generator的学习心得
[Python学习]Iterator 和 Generator的学习心得 Iterator是迭代器的意思,它的作用是一次产生一个数据项,直到没有为止.这样在 for 循环中就可以对它进行循环处理了.那么 ...
- Python Iterator and Generator
Python Iterator and Generator Iterator 迭代器(Iterator)和可迭代对象(Iterable)往往是绑定的.可迭代对象就是我们平时经常用的list ,st ...
- php中trait(性状)与generator(生成器)
PHP中trait(性状)与generator(生成器) 一.trait (性状) 最近在看Josh Lockhat的<Modern PHP>,这本书很薄.但是其中给出了一个很重要的学习方 ...
- RocksDB笔记 - Compaction中的Iterator
Compaction中的Iterator 一般来说,Compaction的Input涉及两层数据的合并,对于涉及到的每一层数据: 如果是level-0,对level-0的每一个sstable文件建立一 ...
- 如何在遍历中使用 iterator/reverse_iterator 删除元素
如何在遍历中使用 iterator/reverse_iterator 删除元素 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公 ...
- 在遍历中使用 iterator/reverse_iterator 进行 Erase 的使用方法
在遍历中使用 iterator/reverse_iterator 进行 Erase 的使用方法 罗朝辉 (http://blog.csdn.net/kesalin/) 本文遵循"署名-非商业 ...
- STL中实现 iterator trail 的编程技巧
STL中实现 iterator trail 的编程技巧 <泛型编程和 STL>笔记及思考. 这篇文章主要记录在 STL 中迭代器设计过程中出现的编程技巧,围绕的 STL 主题为 (迭代器特 ...
- Python3 Iterator and Generator
Python3 Iterator and Generator iterator 主要是利用 iter 函数 >>> list=[1,2,3,4] >>> it = ...
- 关于ArrayList中的iterator返回的事迭代器实例问题。
Arraylist是一个具体的类,它并没有定义它自己的iterator()方法,,它只是从AbstractList 这个抽象类中继承了iterator()这个方法,而AbstractList 中的it ...
随机推荐
- vue与animate.css的结合使用
在vue项目中,由于页面需要动画效果,使用动画其实有多种方式,可以使用vue中的过渡transition,可以使用animate动画与transition配合使用,也可以单独使用animate动画库. ...
- 基本SQL查询
当在数据库的表中存入数据后,就可以查询这些已经存入的数据.下面学习基本SQL查询 本节要点: l 如何使用select语句 Select语句的语法 SELECT语句中的运算 使用DISTINCT和U ...
- 经验之谈—OAuth授权流程图
事实上我们在开发中,常常须要解决获得用户的一些特定的数据,比方:能够选择使用微博登陆.使用QQ登陆等等.然后我们间接的获得用户的头像.昵称等信息.这些都涉及到OAuth授权的内容 OAuth授权有这么 ...
- Unity特殊目录和脚本编译顺序
特殊目录和脚本编译顺序 大多数情况下,您能够选择不论什么你喜欢的目录在您的项目的名称.但unity储备一些名称以指示内容有一个特殊的用途.这些目录中有些会影响脚本编译的顺序.从根本上说,有四个单 ...
- ubuntu解压命令全览(rar)
sudo apt-get install p7zip-full Ubuntu下解压rar文件的方法 2010-05-13 12:47 一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了 ...
- Sublime text3 Emmet使用
Emmet需要配置pyv8 进入 https://github.com/emmetio/pyv8-binaries 下载解压文件放入Sublime Installed Packages下面 就可以使用 ...
- php面向对象之构造函数和析构函数
php面向对象之构造函数和析构函数 简介 php面向对象支持两种形式的构造函数和析构函数,一种是和类同名的构造函数(php5.5之前),一类是魔术方法(php5.5之后).与类名相同的构造函数优先级比 ...
- Jquery validform
一.validform是什么? validform是一款智能的表单验证js插件,它是基于jQuery库与css,我们只需要把表单对象放入, 就可以对整个表 ...
- 50个极好的bootstrap 后台框架主题下载
50个极好的bootstrap 后台框架主题下载 http://sudasuta.com/bootstrap-admin-templates.html 越来越多的设计师和前端工程师开始用bootstr ...
- Qt-信号和槽-1对1
前言:信号和槽是Qt的核心机制,窗体和控件对象之间的沟通一般都使用信号和槽. 对于部件有哪些信号和槽,可以查看help文档. 一.使用自定义槽 1.1 新建工程 新建工程,新建Widget类(基于QW ...