PHP7中的返回类型变得更加严格了。

6

在PHP7.1类型提示中,有没有可能缩小返回类型?

以下代码会导致致命错误Declaration of A::foo(): Obj must be compatible with IA::foo(): IObj,即使缩小返回类型不会破坏继承类型原则:Obj实现了IObj,因此当返回Obj实例时,父类返回类型限制将始终得到满足。

interface IObj {}
class Obj implements IObj {}
interface IA {
    function foo(): IObj;
}

class A implements IA {
    function foo(): Obj {
        return new Obj();
    }
}

我是在做什么错误的事情吗,还是这是PHP的缺陷?

1个回答

6

PHP并不保证Obj实现IObj。因为您随时可以将Obj的声明移动到其他文件中,由于文件是在运行时加载而不是在某个编译步骤中加载,因此完全不知道运行时将加载什么实现Obj并且是否implements IObj

因此,否,您不能更改实现中的返回类型,因为所有类型安全性都将被忽略。只有预编译代码才能保证类型安全性,以预先确定Obj的确切内容。


我不知道有任何编译语言可以让你在子类/实现中更改返回类型。 - Powerlord
作为一个自发的例子,我想到了TypeScript,在其中你可以覆盖几乎任何东西,只要类型保持兼容;如果我现在没有完全疯掉的话。 - deceze
我承认,我更倾向于使用C++、Java或C#。 - Powerlord
@Powerlord 在Java中编译没有问题。当然,你不能将返回类型完全更改为其他类型,但使用一个子类是可以的,因为这不是一种更改,只是对返回类型的严格限制。 - amik
PHP的动态特性使得始终验证协变返回类型变得棘手,这就是为什么它不这样做的原因。撰写返回类型RFC的Levi Morrison确实希望支持它。 - Andrea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接