gpt4 book ai didi

PHP 7 接口(interface),返回类型提示和 self

转载 作者:IT老高 更新时间:2023-10-28 12:00:52 25 4
gpt4 key购买 nike

更新:现在是 PHP 7.4 does support covariance and contravariance它解决了这个问题中提出的主要问题。


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

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

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 Fatal error: Declaration of Foo::bar(int $baz): Foo must be compatible with iFoo::bar(int $baz): iFoo in test.php on line 7

问题是 Foo 是 iFoo 的一个实现,所以据我所知,该实现应该与给定的接口(interface)完全兼容。我大概可以通过更改接口(interface)或实现类(或两者)来通过名称返回提示接口(interface)而不是使用 self 来解决这个问题,但我的理解是语义上 self 表示“返回您刚刚调用该方法的类的实例”。因此,将其更改为接口(interface)在理论上意味着当我的意图是调用实例时,我可以返回实现接口(interface)的任何实例。

这是 PHP 中的疏忽还是经过深思熟虑的设计决定?如果是前者,是否有机会看到它在 PHP 7.1 中得到修复?如果不是,那么返回提示您的界面希望您返回刚刚调用该方法以进行链接的实例的正确方法是什么?

最佳答案

编者按:以下答案已过时。作为php PHP7.4.0,以下是完全合法的:

<?php
Interface I{
public static function init(?string $url): self;
}
class C implements I{
public static function init(?string $url): self{
return new self();
}
}
$o = C::init("foo");
var_dump($o);

原答案:

self 不是指实例,而是指当前类。接口(interface)无法指定必须返回相同的 instance - 以您尝试的方式使用 self 只会强制返回的实例属于同一类。

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

你对self的使用相当于:

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

class Foo implements iFoo
{

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

这是不允许的。


Return Type Declarations RFCthis to say :

The enforcement of the declared return type during inheritance is invariant; this means that when a sub-type overrides a parent method then the return type of the child must exactly match the parent and may not be omitted. If the parent does not declare a return type then the child is allowed to declare one.

...

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.


目前至少你能做的最好是:

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

class Foo implements iFoo
{

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

关于PHP 7 接口(interface),返回类型提示和 self ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39068983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com