我知道如果没有发电机,这可以超级轻松地实现,但我想更好地了解发电机。因此,请不要建议使用其他东西。
我有一个为截图(selenium)生成文件名的类:
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循环的上下文中使用生成器吗?
答案 0 :(得分: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();
?>
答案 1 :(得分:0)
以下是Dark Duck's answer附带的完整代码段。也就是说,它演示了如何使用Iterator接口迭代所有值。 (Duck Duck的代码不完整。)基于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 ...
}