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 类,既不能实例化,也不能子类化。

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.