生成器&迭代器

来源:互联网 发布:阿国网络随笔博客 编辑:程序博客网 时间:2024/06/06 03:08

1.PHP迭代器

当我们使用foreach时,每次迭代都会将当前的元素的值赋给$value并将数组的指针移动指向下一个元素为下一次迭代做准备,从而实现顺序遍历。像这样能够让外部的函数迭代自己内部数据的接口就是迭代器接口,对应的那个被迭代的自己就是迭代器对象。

  • 1 Iterator接口

Iterator接口扩展了Traversable接口,Traversable是一个空接口,它相当于一个标志,所有实现Iterator接口的类肯定也实现了Traversable接口

““
Iterator extends Traversable {

// 返回当前的元素abstract public mixed current(void)// 返回当前元素的键abstract public scalar key(void)// 向下移动到下一个元素abstract public void next(void)// 返回到迭代器的第一个元素abstract public void rewind(void)// 检查当前位置是否有效abstract public boolean valid(void)

}
““

  • 2 Generator类
    Generator提供了一种方便的实现简单的Iterator(迭代器)的方式,使用Generator实现Iterator不需要创建一个类来继承Iterator接口。


Generator implements Iterator {
/* Methods */
public mixed current ( void )
public mixed key ( void )
public void next ( void )
public void rewind ( void )
public mixed send ( mixed $value )
public mixed throw ( Exception $exception )
public bool valid ( void )
public void __wakeup ( void )
}

它实现了Iterator中的5个方法,还提供了三个新方法,其中__wakeup是一个魔术方法,用于序列化,Generator实现这个方法是为了防止序列化。另外两个新方法是throw和send,

  • 迭代器实例

““

2.生成器

相比较迭代器,生成器提供了一种更容易的方法来实现简单的对象迭代,性能开销和复杂性都大大降低。

一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成可以yield生成许多它所需要的值,并且每一次的生成返回值只是暂停当前的执行状态,当下次调用生成器函数时,PHP会从上次暂停的状态继续执行下去。

(迭代)生成器也是一个函数,不同的是这个函数的返回值是依次返回,而不是只返回一个单独的值.或者,换句话说,生成器使你能更方便的实现了迭代器接口.

介绍之前首先看一个例子如果现在要求我们输出1-1000000之前的所有的数字我们应该怎么输出 ?同时我们监控下内存的使用


<?php
echo "foreach start time:", time(), "\n";
echo "foreach start memory:", memory_get_usage(), "\n";
foreach (range(1, 1000000) as $num) {
echo $num, "\n";
}
echo "foreach end time:", time(), "\n";
echo "foreach end memory:", memory_get_usage(), "\n";

执行下输出:


[root@centos-linux work]# php yield.php
foreach start time:1508082920
foreach start memory:227400
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /media/psf/www/work/yield.php on line 4

信息显示,php.ini中的内存分配的问题,默认php代码能够申请到的最大内存字节数就是134217728 bytes,如果代码执行的时候再需要更多的内存,就会报错了。如果想要顺利执行怎么办?

  1. 修改php.ini中memory_limit = 256M

  2. PHP代码中执行前添加set_time_limit(256M);

当然修改扩大申请内存的不是我们主要讲的。这时候我们可以使用生成器,代码如下:

““

原创粉丝点击