【问题标题】:PHP 5.6 Generator Syntax: Can generators only be used in foreach loops?PHP 5.6 生成器语法:生成器只能在 foreach 循环中使用吗?
【发布时间】:2015-06-21 00:17:04
【问题描述】:

我知道不用生成器就可以非常容易地归档,但是我想更好地了解生成器。因此,请不要建议使用其他东西。


我有一个生成屏幕截图文件名的类(硒):

class ScreenshotName
{

    private $counter = 0;

    public function screenshotNameIterator()
    {
         while(true) {
            yield sprintf("screenshot-%s-%s.png", date("Y-m-d\\TH:i:s"), ++$this->counter);
        }
    }
}

现在我的问题是:我可以在除 foreach 循环之外的任何其他上下文中使用这样的生成器吗?例如

(new ScreenshotName())->screenshotNameIterator()->next()

对我来说,这总是返回 null,如果我调试,它永远不会进入生成器方法。 PHP 文档也没有真正提到这一点。

所以我的问题是: 有记录的方法可以在与 for 循环不同的上下文中使用生成器吗?

【问题讨论】:

标签: php generator


【解决方案1】:

这是与Dark Duck's answer 一起使用的完整代码sn-p。也就是说,它演示了如何使用 Iterator 接口来迭代所有值。 (黑鸭的代码不完整。)基于a comment by robert_e_lee on Iterator doc

$gen = evenNumbers();
// If in a method that re-uses an iterator, may want the next line.
//OPTIONAL $gen->rewind();
while ($gen->valid()) {
    // This is the value:
    $value = $it->current();
    // You might or might not care about the key:
    //OPTIONAL $key = $it->key();

    // ... use $value and/or $key ...

    $it->next();
}

上面大致相当于:

foreach (evenNumbers() as $value) {
    // ... use $value ...
}

foreach (evenNumbers() as $key => $value) {
    // ... use $value and/or $key ...
}

【讨论】:

    【解决方案2】:

    有一个记录在案的方法可以做到这一点。事实上,Generator 确实实现了迭代器接口,正如您在 page 上看到的那样。

    事实上,foreach 关键字只适用于迭代器。因此,如果您可以在生成器上使用foreach,您必须能够调用next

    这是一个使用next 代替foreach 的示例代码:

    <?php
    
    function evenNumbers() {
        for ($i = 0;; $i++) {
            yield 2*$i;
        }
    }
    
    $gen = evenNumbers();
    $gen->next();
    echo $gen->current();
    
    ?>
    

    【讨论】:

    • 一个用于说明的代码示例在这里真的很合适,而不是模糊地指向文档。
    • 我按照你的建议添加了
    • @DARK_DUCK:“事实上 foreach 关键字只对迭代器有效”。作为迂腐,我认为这是不正确的。原生数组呢?我做了一些实验,现在我相信即使是生成器也是在 foreach 内部以某种本机方式处理的,而不是作为迭代器。
    猜你喜欢
    • 1970-01-01
    • 2011-09-23
    • 2014-09-06
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 2021-09-16
    • 2017-09-20
    相关资源
    最近更新 更多