PHP 5.6 生成器语法:生成器只能用在 foreach 循环中吗?
PHP 5.6 Generator Syntax: Can generators only be used in foreach loops?
我知道这可以在没有生成器的情况下非常容易地实现,但是我想更好地理解生成器。因此请不要建议使用其他东西。
我有一个 class 可以为屏幕截图生成文件名 (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()
对我来说这总是 returns null,如果我调试,它永远不会进入生成器方法。 PHP 文档也没有真正提到这一点。
所以我的问题是: 是否有记录在案的方法来在与 for 循环不同的上下文中使用生成器?
有记录的方法可以做到这一点。事实上,Generator 确实实现了迭代器接口,正如您在 page.
上看到的那样
事实上 foreach
关键字只对迭代器起作用。所以如果你可以在生成器上使用 foreach
你必须能够调用 next
这是使用 next
而不是 foreach
的示例代码:
<?php
function evenNumbers() {
for ($i = 0;; $i++) {
yield 2*$i;
}
}
$gen = evenNumbers();
$gen->next();
echo $gen->current();
?>
这里是一个完整的代码片段 . That is, it demonstrates how to use Iterator interface to iterate over all values. (Dark Duck's code is not complete.) Based on 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 ...
}
我知道这可以在没有生成器的情况下非常容易地实现,但是我想更好地理解生成器。因此请不要建议使用其他东西。
我有一个 class 可以为屏幕截图生成文件名 (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()
对我来说这总是 returns null,如果我调试,它永远不会进入生成器方法。 PHP 文档也没有真正提到这一点。
所以我的问题是: 是否有记录在案的方法来在与 for 循环不同的上下文中使用生成器?
有记录的方法可以做到这一点。事实上,Generator 确实实现了迭代器接口,正如您在 page.
上看到的那样事实上 foreach
关键字只对迭代器起作用。所以如果你可以在生成器上使用 foreach
你必须能够调用 next
这是使用 next
而不是 foreach
的示例代码:
<?php
function evenNumbers() {
for ($i = 0;; $i++) {
yield 2*$i;
}
}
$gen = evenNumbers();
$gen->next();
echo $gen->current();
?>
这里是一个完整的代码片段
$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 ...
}