Как узнать, выдает ли генератор по ссылке?

Я программирую общий компонент, который обертывает генератор и выполняет рутинные операции:

  • фильтр по ключу
  • преобразовать значение
  • и т.п.

Чтобы максимально точно имитировать обернутый генератор, я хочу использовать ссылки, если генератор использует ссылки.

Когда я пытаюсь выполнить итерацию нереференсного генератора, используя foreach ($generator as $key => &$value) методологии, я получаю следующую ошибку:

Вы можете выполнять итерацию генератора по ссылке только в том случае, если он объявил, что выдает по ссылке

Есть ли способ узнать, возвращает ли данный генератор ссылки? У меня не получилось использовать отражение:

$reflectedGeneratorValueSupplier = new \ReflectionMethod($generator, 'current');
$this->canReference = $reflectedGeneratorValueSupplier->returnsReference(); //always false

Кроме того, итерационный генератор без использования foreach конструкция вообще не работает со ссылками:

while ($generator->valid()) {
    $key = $generator->key();
    $value =& $generator->current(); //error, only variables can be passed by reference
    
    $generator->next();
}

1 ответ

Решение

Использование ReflectionGenerator, а затем getFunction, похоже, работает.

http://sandbox.onlinephpfunctions.com/code/92ed79dc7a6e925243f0c55898a5d1170f994189

<?php

function &generate(&$arr)
{
    foreach ($arr as $key => &$value) {
        yield $key => $value;
    }
};

$input = range(0,100);
$generator = generate($input);

$r = new ReflectionGenerator ($generator);

var_dump($r->getFunction()->returnsReference()); // true
Другие вопросы по тегам