PHP Generator::rewind() 方法

返回上一级

PHP Generator::rewind() 方法用于重置一个生成器。

( PHP 5 >= 5.5.0, PHP 7 )

方法原型

PHP Generator::rewind() 方法的原型如下

public void Generator::rewind ( void )

在迭代器中,该方法会将一个迭代器重新指向第一个元素。但是,在生成器中,一旦迭代已经开始,那么该方法会抛出一个异常。

这个方法存在的目的,主要原因还是因为兼容迭代器。毕竟,我们的 Generator 类是实现了 Iterator 接口的。

范例一

一旦迭代器已经开始,该方法就会抛出一个异常,我们写一小段代码演示下

<?php

function gen_zero_to_ten() {
    for ($i = 1; $i <= 10; $i++) {
        yield $i;
    }
}

$generator = gen_zero_to_ten();
foreach ($generator as $key => $value) {
    echo $key ," => ", $value, "\n";
    $generator->rewind();
}

输出结果如下

0 => 1
1 => 2

Fatal error: Uncaught Exception: Cannot rewind a generator that was already run in

咦,大家有没有发现,一般来说,输出 0 => 1 应该就会报错才对,可实际上确是在第二次输出了才报错。

百思不得其解。

哈哈,在妙用中我发现了为什么了 ? 我们一直以为,调用了该函数应该就会立即抛出异常,实际上不是的,是只有等到下一次调用运行完 yield 后才抛出异常。这样,输出 1=> 2 就比较合理了。

Generator::rewind() 的妙用

Generator::rewind() 方法并不是全无用处,在某些场合还是非常有用的。

在实际应用中,我们可以使用这个方法来测试生成器。因为 Generator::rewind() 方法会执行我们的生成器函数,直到遇到第一个 yield 语句。

比如,如果我们使用生成器来读取一个不存在的文件,一般来说我们只有在 foreach() 的第一次时才会触发错误。但如果迭代之前先调用了 Generator::rewind(),那么我们就能及早的发现错误。

例如下面这段代码

<?php

function getLines($file) {
    $f = fopen($file, 'r');
    try {
        while ($line = fgets($f)) {
            yield $line;
        }
    } finally {
        fclose($f);
    }
}

$getLines = getLines('no_such_file.txt');
$getLines->rewind(); // 调用 rewind() 方法,如果生成器发生错误,就能及早发现,也就不会发生清理日志的动作

openAndClearLogFile();

foreach ($getLines as $n => $line) { 
    // 如果没有调用 rewind() 方法,那么直到此处才发现文件不存在,这时会发现日志已经清理完毕了。
    writeToLogFile('reading: ' . $line . "\n");
}

closeLogFile();

返回上一级

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

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

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