SerafimArts
@SerafimArts
Senior Notepad Reader

Как работать с корутинами на чтение и запись одновременно?

Собственно сабж, допустим у нас есть корутинка:

foreach ($items as $item) {
    yield $item;
}

// foreach (myfoo() as  $item) ...


Возвращает ссылку на итератор "итемов", а вот такая подменяет их:

foreach ($items as &$item) {
  $item = yield;
}

// while ($iterator = myfoo()) { $iterator->send(23); }


Если совместить, получаем примерно такой вариант:

foreach ($items as &$item) {
    $item = (yield $item);
}

// while ($iterator = myfoo()) { $iterator->current() === 42 ?: $iterator->send(23); }


В последнем случае происходит сдвиг итераций и вместо, допустим, 10 итераций мы получаем 5 с шагом 2. Для исправления этого можно воспользоваться таким вариантом:

foreach ($items as &$item) {
    $item = yield (yield $item);
}


В этом случае можно и "читать" и "писать", но это лишь костыль, т.к. пропустить "тик" записи невозможно, произойдёт дублирование текущего.

Можно попробовать передать генератор по ссылке в качестве аргумента:

function myfoo(Generator $writer = null): Generator
{
    foreach ($items as &$item) { 
        yield $item;
        if ($writer !== null) {
            $item = $writer->current(); // $writer->next() ?
        }
    }
}

// myfoo(yield ээээээ.... А дальше что писать? На этом мои полномочия всё (с)


Что-то вообще не могу придумать никаких универсальных решений, чтобы функцию можно было использовать как на чтение, так и на чтение + запись.

Есть хоть какие-то идеи? =)

UPD: Придумался вот такой вариант:

foreach ($items as &$item) {
  $data = (yield $item);

  if ($data !== null) {
      $item = $data;
      yield $item;
  }
}


Но проблема в том, что он пишет в элемент N+1, а не текущий. Т.е. можно лишь внедряться в данные после текущего "тика", а не подменять их, оставаясь на текущем =(

$i = 0;
foreach ($reader = myfoo() as $value) {
  echo ++$i . ') ' . $value . "\n";
  $reader->send($i);
}


В результате получим что-то вроде:

1) 2
2) 3
3) 4
и т.д
.
  • Вопрос задан
  • 218 просмотров
Решения вопроса 1
SerafimArts
@SerafimArts Автор вопроса
Senior Notepad Reader
Всем спасибо, вопрос решён.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
19 апр. 2024, в 05:01
999999 руб./за проект
19 апр. 2024, в 03:52
1000 руб./за проект
19 апр. 2024, в 03:01
1000 руб./за проект