iterator — повторение дважды итеративного типа

В PHP 7.1 появился новый итерируемый псевдотип, который абстрагирует массивы и Traversable объекты.

Предположим, что в моем коде у меня есть такой класс:

class Foo
{
private $iterable;

public function __construct(iterable $iterable)
{
$this->iterable = $iterable;
}

public function firstMethod()
{
foreach ($this->iterable as $item) {...}
}

public function secondMethod()
{
foreach ($this->iterable as $item) {...}
}
}

Это работает нормально $iterable это массив или Iteratorкроме случаев, когда $iterable это Generator, В этом случае на самом деле, звоня firstMethod() а потом secondMethod() будет производить следующее Exception: Cannot traverse an already closed generator,

Есть ли способ избежать этой проблемы?

3

Решение

Генераторы не могут быть перемотаны. Если вы хотите избежать этой проблемы, вы должны сделать новый генератор. Это может быть сделано автоматически, если вы создаете объект, который реализует IteratorAggregate:

class Iter implements IteratorAggregate
{
public function getIterator()
{
foreach ([1, 2, 3, 4, 5] as $i) {
yield $i;
}
}
}

Затем просто передайте экземпляр этого объекта в качестве итератора:

$iter = new Iter();
$foo = new Foo($iter);
$foo->firstMethod();
$foo->secondMethod();

Выход:

1
2
3
4
5
1
2
3
4
5
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]