【发布时间】:2016-12-28 09:10:21
【问题描述】:
更新:PHP 7.4 现在does support covariance and contravariance 解决了这个问题中提出的主要问题。
我在 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");
预期的输出是:
弗雷德 威尔玛 巴尼 贝蒂
我实际得到的是:
PHP 致命错误:声明 Foo::bar(int $baz): Foo must be compatible with iFoo::bar(int $baz): iFoo in test.php on line 7
问题是 Foo 是 iFoo 的一个实现,所以据我所知,该实现应该与给定的接口完全兼容。我大概可以通过更改接口或实现类(或两者)来通过名称返回提示接口而不是使用self来解决这个问题,但我的理解是语义上self意味着“返回类的实例您刚刚调用了该方法”。因此,将其更改为接口在理论上意味着当我的意图是调用实例时,我可以返回实现接口的任何实例。
这是 PHP 中的疏忽还是经过深思熟虑的设计决定?如果是前者,是否有机会看到它在 PHP 7.1 中得到修复?如果不是,那么返回提示您的界面希望您返回刚刚调用该方法以进行链接的实例的正确方法是什么?
【问题讨论】:
-
我认为这是 PHP 返回类型提示中的错误,也许您应该将其提升为 bug;但是在这个后期阶段,任何修复都不太可能进入 PHP 7.1
-
由于 7.1 的最后一个 beta 版本已于几天前上线,因此任何修复都不太可能进入 7.1。
-
出于兴趣,您在哪里阅读您对
self返回类型应该如何工作的解释? -
@Adam:
self的意思是“返回你调用它的实例,而不是其他实现相同接口的实例”似乎是合乎逻辑的。我似乎记得 Java 也有类似的返回类型(尽管我已经有一段时间没有进行任何 Java 编程了) -
嗨,戈登。好吧,除非它被记录在某个地方可以工作,否则我不会指望什么可能是合乎逻辑的现实。 TBH 对于我所描述的情况,我会尽可能地声明并使用 iFoo 作为返回类型。是否存在实际上不起作用的情况? (我意识到这是“建议”/意见而不是“答案”。
标签: php interface return-type php-7 type-hinting