PHP 生成器类 Generator
前面章节中我们有提到 PHP 的生成器函数会返回一个生成器对象。其实这个生成器对象其实是就是 Generator
类的实例。
<?php function gen_one_to_three() { for ($i = 1; $i <= 3; $i++) { yield $i; } } var_dump(gen_one_to_three());
运行上面这段代码,输出结果为
object(Generator)#1 (0) {}
本章,我们来看看这个生成器类 Generator
PHP Generator 类
PHP Generator
类是 PHP 仅有的几个 「 预定义接口和类之一 」 。 而且这个类不可以使用 new
关键字来创建一个实例。
虽然不能创建实例。但是所有的生成器对象都是它的实例。
PHP Generator
类实现了 Iterator
接口。也就是说,可以使用迭代器的场合和函数,同样适用于生成器,我们来看看生成器提供了哪些方法
<?php final class Generator implements Iterator { /* Methods */ public mixed current ( void ) public mixed key ( void ) public void next ( void ) public void rewind ( void ) public bool valid ( void ) public mixed getReturn ( void ) public mixed send ( mixed $value ) public mixed throw ( Throwable $exception ) public void __wakeup ( void ) }
在这个类定义中,前 5 个方法是实现 Iterator 接口所必须的。 中间三个方法是生成器所特有的,对应了生成器的几种语法。
__wakeup()
方法的意思生成器也可以被序列化和反序列化 ?
P.S 其实这个类是一个
final
类,但官方文档中没有标明,这意味着这个类既不能被实例化,也不能被子类化
PHP Generator 类方法说明
方法 | 说明 |
---|---|
Generator::current() | 获取迭代器当前 yield 的值 |
Generator::key() | 获取迭代器当前 yield 的键 |
Generator::next() | 继续执行生成器 |
Generator::rewind() | 重置迭代器 |
Generator::valid() | 判断迭代器是否已经被关闭 |
Generator::send() | 发送一个值给迭代器 |
Generator::throw() | 触发一个异常并传递给迭代器 |
Generator::getReturn() | 获取迭代器的返回值 |
Generator::__wakeup() | 反序列化时的回调方法 |
需要注意的是:这个 Generator 类因为不能使用 new 来实例化,因此,从某些方面说,即使继承这个子类并实现了所有方法并不是创建了一个生成器。只能说是创建了一个迭代器。
虽然这个 Generator 类不能实例化,但是因为任意一个生成器都是这个类的实例,因此我们可以调用相关的方法来实现很多很酷炫的功能。
错误范例一
实例化一个 Generator 类
$gen = new Generator();
运行上面的代码,输出结果如下
Fatal error: Uncaught Error: The "Generator" class is reserved for internal use and cannot be manually instantiated in /Users/yufei/workspace/gradle/helloworld/demo.php:2
错误范例二
继承 Generator 类并实例化一个子类
<?php class MyGenerator extends Generator{} $gen = new MyGenerator();
运行结果为
Fatal error: Class MyGenerator may not inherit from final class (Generator)
哇,等等,原来这一个 final
类,既不能实例化,也不能子类化。