В 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
,
Есть ли способ избежать этой проблемы?
Генераторы не могут быть перемотаны. Если вы хотите избежать этой проблемы, вы должны сделать новый генератор. Это может быть сделано автоматически, если вы создаете объект, который реализует 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
Других решений пока нет …