【问题标题】:Narrow return type in PHP7PHP7 中的窄返回类型
【发布时间】:2018-04-23 19:38:10
【问题描述】:

是否可以在 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 的缺点?

【问题讨论】:

    标签: php type-hinting php-7.1


    【解决方案1】:

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

    所以,不,您不能在实现中更改返回类型,因为那时所有类型安全都会消失。只有预先编译确定Obj 的确切含义的代码,才能保证类型安全。

    【讨论】:

    • 我不知道有任何编译语言可以让您更改子类/实现中的返回类型。
    • 作为一个自发的例子 TypeScript 浮现在脑海中,只要类型保持兼容,您几乎可以覆盖任何东西;如果我现在还没有完全摆脱摇滚乐。
    • 我承认,我更多地考虑 C++、Java 或 C#。
    • @Powerlord 它在 Java 中编译得很好。当然,您不能将返回类型更改为完全不同的任何东西,但是使用后代很好,因为这不是更改,只是增加了返回类型的严格性。
    • PHP 的动态特性使得一致地验证协变返回类型变得很棘手,这就是它不这样做的原因。负责返回类型 RFC 的 Levi Morrison 确实希望支持它。
    猜你喜欢
    • 2016-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    相关资源
    最近更新 更多