PHP Traversable 类型提示
Posted
技术标签:
【中文标题】PHP Traversable 类型提示【英文标题】:PHP Traversable type hint 【发布时间】:2013-06-06 13:43:00 【问题描述】:我有一个相对简单的函数,它使用 foreach
function foo($t)
$result;
foreach($t as $val)
$result = dosomething($result, $val);
return $result;
我想输入提示,Traversable
似乎正是我需要的输入提示
function foo(Traversable $t)
但是,当使用数组时,这会给出E_RECOVERABLE_ERROR
(当然可以在foreach
中使用):example
Argument 1 passed to foo() must implement interface Traversable, array given
有没有办法输入提示或者这是不可能的?
【问题讨论】:
来自手册(您发布的链接):Abstract base interface that cannot be implemented alone. Instead it must be implemented by either IteratorAggregate or Iterator.
我相信你实际上可以使用array
作为提示,我会测试我的理论,是的,你可以
@alfasin 因此任何实现Iterator
的类也将匹配Traversable
,因为Iterator
是Traversable
的子类型。基本 OOP 机制
请考虑提供给comment in manual 的解决方案。顺便说一句,I asked a similar question.
@Dale 我提前道歉,因为我必须遗漏一些东西:Array don't implement Iterator (AFAIK), and you're trying to use Array, no?
【参考方案1】:
这里有一个错误:#41942。关闭为“不是错误”。由于 php 数组不是对象,它们无法实现接口,因此无法同时输入 array
和 Traversable
的提示。
您可以使用iterator_to_array
、ArrayIterator
或省略类型提示。请注意,iterator_to_array 会将整个迭代器复制到一个数组中,因此可能效率低下。
// These functions are functionally equivalent but do not all accept the same arguments
function foo(array $a) foobar($a);
function bar(Traversable $a) foobar($a);
function foobar($a)
foreach($a as $key => $value)
$array = array(1,2,3)
$traversable = new MyTraversableObject();
foo($array);
foo(iterator_to_array($traversable));
bar(new ArrayIterator($array));
bar($traversable);
foobar($array);
foobar($traversable);
【讨论】:
你也可以通过foo(new ArrayIterator(array(1,2,3))
将数组转换为对象。【参考方案2】:
问题是,数组不是对象,所以它们不能实现接口。所以你不能同时输入提示,array
和 Traversable
。
【讨论】:
是否还有其他 PHP 原生实体可以在foreach
中使用但不实现 Traversable
?
不,但您可以编写自己的类来实现IteratorAggregate
或Iterator
,并且它们扩展Traversable
但就是这样:foreach
中的所有对象都可迭代。如果对象实现了Traversable
,则将遍历迭代器(或聚合迭代器),否则将遍历对象的公共属性php.net/manual/en/control-structures.foreach.php【参考方案3】:
同样的问题。我已经放弃了,我只是手动编写函数中的所有内容。
这应该会给你你想要的功能:
function MyFunction($traversable)
if(!$traversable instanceof Traversable && !is_array($traversable))
throw new InvalidArgumentException(sprintf(
'Myfunction($traversable = %s): Invalid argument $traversable.'
,var_export($traversable, true)
));
编辑
如果您只想显示$traversable
的类型。如果您希望在子类中继承该功能。
public function MyMethod($traversable)
if(!$traversable instanceof Traversable && !is_array($traversable))
throw new InvalidArgumentException(sprintf(
'%s::MyMethod($traversable): Invalid argument $traversable of type `%s`.'
,get_class($this)
,gettype($traversable)
));
【讨论】:
【参考方案4】:PHP 7.1 为此引入了iterable
type declaration,它接受\Traversable
的数组和实例。
在以前的版本中,您必须省略类型声明。
【讨论】:
以上是关于PHP Traversable 类型提示的主要内容,如果未能解决你的问题,请参考以下文章