本文介绍了PHP 7接口,返回类型提示和自我的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在PHP 7中使用返回类型提示遇到了一些问题。我的理解是暗示:self 意味着你打算让一个实现类返回本身。因此我在我的接口中使用:self 来表示,但是当我尝试实际实现接口时,我遇到了兼容性错误。

I have run into something of an issue with using return type hinting in PHP 7. My understanding is that hinting : self means that you intend for an implementing class to return itself. Therefore I used : self in my interfaces to indicate that, but when I tried to actually implement the interface I got compatibility errors.

以下是我遇到的问题的简单演示:

The following is a simple demonstration of the issue I've run into:

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");

预期产出为:

我实际获得的是:

事情是Foo是iFoo的一个实现,所以就我而言可以告诉实现应该与给定的接口完全兼容。我可以通过更改接口或实现类(或两者)来修复此问题,以返回通过名称提示接口而不是使用 self ,但我的理解是在语义上 self 表示返回刚刚调用方法的类的实例。因此,将其更改为接口意味着理论上我可以返回实现接口的任何实例,而我的意图是调用实例将返回的内容。

The thing is Foo is an implementation of iFoo, so as far as I can tell the implementation should be perfectly compatible with the given interface. I could presumably fix this issue by changing either the interface or the implementing class (or both) to return hint the interface by name instead of using self, but my understanding is that semantically self means "return the instance of the class you just called the method on". Therefore changing it to the interface would mean in theory that I could return any instance of something that implements the interface when my intent is for the invoked instance is what will be returned.

这是PHP的疏忽还是这是一个刻意的设计决定?如果它是前者有任何机会在PHP 7.1中看到它修复?如果没有,那么正确的返回提示是什么,你的接口希望你返回刚刚调用方法的实例进行链接的正确方法是什么?

Is this an oversight in PHP or is this a deliberate design decision? If it's the former is there any chance of seeing it fixed in PHP 7.1? If not then what is the correct way of return hinting that your interface expects you to return the instance you just called the method on for chaining?

推荐答案

self 不引用实例,它指的是现在的课程。接口无法指定必须返回相同的实例 - 使用 self 以您尝试的方式只强制执行该操作返回的实例属于同一个类。

self does not refer to the instance, it refers to the current class. There is no way for an interface to specify that the same instance must be returned - using self in the manner you're attempting would only enforce that the returned instance be of the same class.

也就是说,PHP中的返回类型声明必须是不变的,而你正在尝试的是协变的。

That said, return type declarations in PHP must be invariant while what you're attempting is covariant.

您使用 self 相当于:

interface iFoo
{
    public function bar (string $baz) : iFoo;
}

class Foo implements iFoo
{

    public function bar (string $baz) : Foo  {...}
}

这是不允许的。

具有:

...

此RFC最初提出了协变返回类型,但由于一些问题而被更改为不变量。可以在将来的某个时间点添加协变返回类型。

This RFC originally proposed covariant return types but was changed to invariant because of a few issues. It is possible to add covariant return types at some point in the future.






For至少你能做的最好的时间是:


For the time being at least the best you can do is:

interface iFoo
{
    public function bar (string $baz) : iFoo;
}

class Foo implements iFoo
{

    public function bar (string $baz) : iFoo  {...}
}

这篇关于PHP 7接口,返回类型提示和自我的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 06:17