这是一个简单的 JavaScript 生成器(来自:http://blog.carbonfive.com/2013/12/01/hanging-up-on-callbacks-generators-in-ecmascript-6/)
function* powGenerator() {
var result = Math.pow(yield "a", yield "b");
return result;
}
var g = powGenerator();
console.log(g.next().value); // "a", from the first yield
console.log(g.next(10).value); // "b", from the second
console.log(g.next(2).value); // 100, the result
我正在尝试用 PHP 模拟一些类似的东西,但这有点让人头疼。
<?php
function powGenerator() {
return pow((yield 'a'), (yield 'b'));
}
在我继续之前,我在 PHP 中遇到了这个错误
Fatal error: Generators cannot return values using "return"
好吧,也许我会使用另一个 yield 来获取最终值? ...
<?php
function powGenerator() {
yield pow((yield 'a'), (yield 'b'));
}
$g = powGenerator(); //=> Generator {#180}
echo $g->send(10); //=> "b"
echo $g->send(2); //=> 100
好的,所以我找回了我的值(value),但这里有两个主要问题
我的
"a"
去了哪里? — 注意在 JS 示例中我能够访问"a"
和“b”
产生值以及100
最终结果。生成器还没有完成! — 我必须再调用一次
send
来完成生成器$g->valid(); //=> true $g->send('?'); //=> null $g->valid(); //=> false
来自 PHP Generator::send
public mixed Generator::send ( mixed $value )
Sends the given value to the generator as the result of the current
yield
expression and resumes execution of the generator.If the generator is not at a
yield
expression when this method is called, it will first be let to advance to the firstyield
expression before sending the value. As such it is not necessary to "prime" PHP generators with a Generator::next() call (like it is done in Python).
强调“因此没有必要使用 Generator::next()
来“启动”PHP 生成器”。好的,但这到底是什么意思?我不必像 JavaScript 示例那样“启动”它,但第一个产生的值也会被吞没。
谁能解释一下您是如何在不使用foreach
的情况下单步执行生成器的?
最佳答案
第一个产生的值并没有被吞噬,你只是从未看过它。
$g = powGenerator();
echo $g->current(); //a
然后你两次发送值并恢复执行,$g->valid()
在这之后是 true
因为你在第三次之后还没有恢复 yield
- 生成器尚未完成,可能还有更多工作要做。考虑:
function powGenerator() {
yield pow((yield 'a'), (yield 'b'));
echo "Okay, finishing here now!\n";
}
$g = powGenerator();
echo $g->current(), "\n"; //a
echo $g->send(10), "\n"; //b
echo $g->send(2), "\n"; //100
$g->next(); // Resumes execution of the generator,
// which prints its own message and completes.
var_dump($g->valid()); //false
这将输出:
a
b
100
Okay, finishing here now!
bool(false)
现在在 PHP 7 中,您可以 return from a generator .
function powGenerator() {
return pow((yield 'a'), (yield 'b'));
echo "This will never print.";
}
$g = powGenerator();
echo $g->current(), "\n"; //a
echo $g->send(10), "\n"; //b
echo $g->send(2), "\n"; // Prints just the newline, you're moving on
// to a return which you must get explicitly.
var_dump($g->valid()); // Generator complete, you're free to get the return.
echo $g->getReturn(), "\n";
哪些输出:
a
b
bool(false)
100
至于在没有 foreach
的情况下单步执行它们 - Generator工具 Iterator ,所以它有适当的方法来处理它:current , key , next , rewind , 和 valid .需要注意的是,如果您在已经开始的生成器上调用它,rewind
将抛出异常。
执行此操作并演示 PHP 7 的新 generator delegation 的示例:
function letterGenerator() {
yield from range('a', 'z');
}
$g = letterGenerator();
while ($g->valid()) {
echo $g->current();
$g->next();
}
输出:
abcdefghijklmnopqrstuvwxyz
关于php - 如何在没有 foreach 的情况下使用 PHP 生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32960408/