Вот простой генератор 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
Неустранимая ошибка: генераторы не могут возвращать значения, используя «возврат»
Хорошо, возможно, я просто использую другую доходность, чтобы получить окончательное значение? …
<?php
function powGenerator() {
yield pow((yield 'a'), (yield 'b'));
}
$g = powGenerator(); //=> Generator {#180}
echo $g->send(10); //=> "b"echo $g->send(2); //=> 100
Итак, я вернул себе значение, но здесь есть две главные проблемы
Где мой "a"
идти? — Обратите внимание на пример JS, я смог получить доступ к обоим "a"
и "b"
дали значения, а также 100
конечный результат.
Генератор еще не готов! — Я должен позвонить send
дополнительное время для завершения генератора
$g->valid(); //=> true
$g->send('?'); //=> null
$g->valid(); //=> false
Из PHP Генератор :: отправить
public mixed Generator::send ( mixed $value )
Посылает данное значение в генератор как результат тока
yield
Выражение и возобновляет выполнение генератора.Если генератор не на
yield
Выражение, когда этот метод вызывается, он сначала будет позволено перейти к первомуyield
Выражение перед отправкой значения. Таким образом, нет необходимости «заправлять» генераторы PHP Генератор :: следующая () вызов (как это делается в Python).
Акцент на «как таковой» не обязательно «заправлять» генераторы PHP Generator::next()
«Хорошо, но что это на самом деле означает? Мне не нужно« заправлять »это как пример 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 вы Можно возврат от генератора.
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
— Генератор инвентарь Итератор, так что у него есть подходящие методы, чтобы рассматривать его как таковой: ток, ключ, следующий, перемотка, а также действительный. С оговоркой, что rewind
вызовет исключение, если вы вызовете его на генераторе, который уже начался.
Пример, который делает это, а также демонстрирует новый PHP 7 генерация делегирования:
function letterGenerator() {
yield from range('a', 'z');
}
$g = letterGenerator();
while ($g->valid()) {
echo $g->current();
$g->next();
}
Выход:
abcdefghijklmnopqrstuvwxyz
Других решений пока нет …