在 PHP 中使用 Foreach 在 IteratorAggregates 中生成
Yielding in IteratorAggregates with Foreach in PHP
我在 PHP 中有一个带有私有数组字段的 class,并通过遍历该数组并产生新值来实现 IteratorAggregate。
class Item implements IteratorAggregate{
private static $items = array(
'a' => array(1, 2);
'b' => array(3, 4);
'c' => array(5, 6);
);
public function getIterator() {
return array_walk(Item::$items, function ($value, $key) {
yield array('letter' => $key, 'number' => $value[0]);
});
}
}
然后我尝试将此 class 的新实例传递给 foreach
子句:
foreach((new Item()) as $value){
process($value);
}
然而,这失败得很惨:
Fatal error: Uncaught exception 'Exception' with message 'Objects
returned by Item::getIterator() must be traversable or
implement interface Iterator'
然而,据我了解,我的 class 是可遍历的,因为它实现了 IteratorAggregate。
关于我做错了什么有什么建议吗?我可以重写它以将产量转换为数组,但这并不能解释为什么我会收到我收到的错误。
在您的代码中,yield
适用于闭包,而不适用于方法。这意味着传递给 array_walk
的闭包是一个生成器,getIterator
现在只是一个普通方法,return 是 array_walk
的 return 值(这是一个数组)。
只需使用 foreach
而不是 array_walk
:
class Item implements IteratorAggregate{
private static $items = array(
'a' => array(1, 2),
'b' => array(3, 4),
'c' => array(5, 6),
);
public function getIterator() {
foreach (self::$items as $key => $value) {
yield array('letter' => $key, 'number' => $value[0]);
}
}
}
我在 PHP 中有一个带有私有数组字段的 class,并通过遍历该数组并产生新值来实现 IteratorAggregate。
class Item implements IteratorAggregate{
private static $items = array(
'a' => array(1, 2);
'b' => array(3, 4);
'c' => array(5, 6);
);
public function getIterator() {
return array_walk(Item::$items, function ($value, $key) {
yield array('letter' => $key, 'number' => $value[0]);
});
}
}
然后我尝试将此 class 的新实例传递给 foreach
子句:
foreach((new Item()) as $value){
process($value);
}
然而,这失败得很惨:
Fatal error: Uncaught exception 'Exception' with message 'Objects returned by Item::getIterator() must be traversable or implement interface Iterator'
然而,据我了解,我的 class 是可遍历的,因为它实现了 IteratorAggregate。
关于我做错了什么有什么建议吗?我可以重写它以将产量转换为数组,但这并不能解释为什么我会收到我收到的错误。
在您的代码中,yield
适用于闭包,而不适用于方法。这意味着传递给 array_walk
的闭包是一个生成器,getIterator
现在只是一个普通方法,return 是 array_walk
的 return 值(这是一个数组)。
只需使用 foreach
而不是 array_walk
:
class Item implements IteratorAggregate{
private static $items = array(
'a' => array(1, 2),
'b' => array(3, 4),
'c' => array(5, 6),
);
public function getIterator() {
foreach (self::$items as $key => $value) {
yield array('letter' => $key, 'number' => $value[0]);
}
}
}