yield from и проблема с возвратом массива значений
Данная написанная мною программа должна осуществлять генерацию и вывод всех возможным комбинаций из трёх цифр, которые могут принимать значения от 1 до 6, проще говоря программа генерирует все возможные варианты броска трёх игральных костей. Проблема заключается в возврате и выводе массива каждой комбинации. Я ожидал, что возврат массива значений $values будет происходит на команде yield values однако программа не возвращала массив комбинаций и заканчивалась по причине нехватки места Fatal error: Allowed memory size of 1610612736 bytes exhausted. Но при добавлении следующей команды return values , уже начал происходить возврат комбинаций. Почему без return values моя программа не работает. До этого я думал, прочитав документацию, что return в генераторах нам необходим только в случае , если нам нужен возврат значений с помощью функции getReturn().
function generateCombinations($n, $values)
{
if (count($values) == $n) {
yield $values;
return $values; // Почему-то не работает без return
}
for ($i = 1; $i <= 6; $i++) {
yield from generateCombinations($n, array_merge($values, [$i]));
}
}
$generator = generateCombinations(3, []);
foreach ($generator as $value) {
print_r($value);
}
?>
Ответы (1 шт):
Проблема решена. Протестировав программу без команды return $values выяснилось, что программа, после срабатывания условного оператора и возврата комбинации [1,1,1], продолжала свое выполнение, так как функция yield возвращает текущее значение, и при следующем вызове функции она возобновит выполнения с места, на котором прервалась. Далее происходил вызов функции generateCombinations(3, [1,1,1,1]) и потом опять и опять с массивом на 1 элемент больше, то есть она зацикливалась и заканчивала свою работу из-за нехватки памяти. Когда, я добавлял команду return $values происходило прекращение работы функции и возврат массива $values и дальше происходила итерация по генератору.
Также можно было обойстись без команды return. Сделав каким-нибудь образом конец функции, например так:
<?php
function generateCombinations($n, $values)
{
if (count($values) == $n) {
yield $values;
} else {
for ($i = 1; $i <= 6; $i++) {
yield from generateCombinations($n, array_merge($values, [$i]));
}
}
}
$generator = generateCombinations(3, []);
foreach ($generator as $value) {
print_r($value);
}
?>
Добавив команду else, то есть изменив условный оператор так, что бы цикл с добавление единицы в массив не срабатывал при выполнения условия if (count($values) == $n). Тогда функция будет возвращать массив по команде yield $values , и в цикл она дальше не попадет и функция закончиться.