更新:PHP 7.4现在支持协变和逆变,解决了此问题中提出的主要问题。
我在使用PHP 7中的返回类型提示时遇到了一些问题。 我的理解是,使用: self
表示您打算让实现类返回自身。 因此,我在我的接口中使用: self
来表示这一点,但当我尝试实际实现接口时,我收到了兼容性错误。
以下是我遇到问题的简单演示:
interface iFoo
{
public function bar (string $baz) : self;
}
class Foo implements iFoo
{
public function bar (string $baz) : self
{
echo $baz . PHP_EOL;
return $this;
}
}
(new Foo ()) -> bar ("Fred")
-> bar ("Wilma")
-> bar ("Barney")
-> bar ("Betty");
期望的输出是:
Fred Wilma Barney Betty
实际获取的输出是:
PHP致命错误:test.php第7行,Foo::bar(int $baz)的声明必须与iFoo::bar(int $baz)兼容: Foo必须与所给接口兼容。
问题在于Foo是iFoo的实现,因此就我所知,实现应该与给定接口完全兼容。我可以通过更改接口或实现类(或两者)来使用接口名称而不是使用self
返回提示使之正常,但据我了解,语义上self
表示“返回刚刚调用方法的类的实例”。因此,将其更改为接口将意味着理论上我可以返回实现接口的任何实例,而我的意图是返回被调用的实例。
这是PHP的疏忽还是故意设计的?如果前者,在PHP 7.1中修复它的机会有多大?如果没有,那么正确的方式是什么?提示您的接口希望您返回刚刚调用的实例以进行链接?
self
返回类型应该如何工作的解释呢? - Adam Cameronself
代表“返回调用此方法的实例,而不是实现相同接口的其他实例”是很合理的。我记得Java有类似的返回类型(虽然我已经有一段时间没有写Java程序了)。 - GordonM