PHP 7.1 - 为什么没有关于无效返回值的警告?



PHP 手册在 PHP 7.1 中添加的新void返回类型的概述中指出了这一点:

尝试使用 void 函数的返回值只会计算为 NULL,而不会发出任何警告。这样做的原因是,警告会暗示使用通用的高阶函数。

">警告将暗示使用高阶函数"是什么意思?

高阶函数 (HOF( 是至少遵循以下条件之一的函数 -

  • 将一个或多个函数作为参数
  • 返回函数作为其结果

然后从 PHP Void RFC:

由于returnreturn null; 在 PHP 中在技术上是等价的;当未指定返回值时,PHP 将为您生成null。但是,选择一个而不是另一个表明意图。如果指定一个值,则表明该值很重要。在 void 函数中,返回值是微不足道的:它总是相同的,没有实际的用处。使用返回 null 显式指定它;毫无意义,因为函数将返回什么值并不重要。

(我的亮点(

因此,根本不需要提供警告,它只需要使用另一个函数和额外的大量编译时开销来通知一段故意不返回的代码的返回错误。

可以这样想:

  • 我会保留很多海绵待命,以防空牛奶盒被撞倒。

纸箱总是故意空的,所以没有必要去商店买 12 块高吸水性海绵!


要准确查看将调用哪些函数,请尝试探索 PHP 7 的(开源(编译时错误处理逻辑;查看将调用哪些函数来处理导致类似错误的函数(例如返回无法识别或不正确的类型(。

这些函数不是通过静默返回null而不是 PHP 7.1 上的错误来调用的函数,而是void返回类型。

问题是这样的情况:

class Forwarder {
public $obj; // Some object
public function __call($method, $args) {
return $this->obj->$method(...$args);
}
}
class Obj {
public function returnsVal(): int { return 42; }
public function returnsVoid(): void { return; }
}
$fwd = new Forwarder;
$fwd->obj = new Obj;
// We want both of these calls to work
$val = $fwd->returnsVal();
$fwd->returnsVoid();

此代码可以处理 void 和非 void 函数。如果使用 void 函数的返回值会发出警告,那么我们将无法编写此代码,而必须执行类似操作:

class Forwarder {
public $obj; // Some object
public function __call($method, $args) {
if (returns_void($this->obj, $method)) {
$this->obj->$method(...$args);
} else {
return $this->obj->$method(...$args);
}
}
}

这是很多不必要的样板文件,更不用说"returns_void"必须使用昂贵的反射调用来实现。

作为Martin回答的附录,我相信Void RFC中的以下部分也有助于澄清这个问题:

在表达式中使用 void 函数

在其他一些语言(如 C(中,void 函数不能在表达式中使用,只能用作语句。由于此 RFC 添加了一种为 PHP 语法指定 void 函数的方法,因此可以预期相同的限制现在将适用于 PHP。但是,这与先例不符。PHP 自成立以来就以内置函数的形式拥有某种"void 函数",在手册中记录为"void"。与 C 不同,此类函数可以在表达式中使用。

我们可以更改 PHP 关于 void 函数的规则并禁止在表达式中使用它们,但这会产生一个向后兼容性问题:现有的 PHP 代码依赖于能够在表达式中调用内置的 void 函数,这并非不可想象,并且大量代码假设您可以获取任意 PHP 函数的返回值(回调, 也许(。

此外,IDE 和其他工具可以在使用 void 函数的返回值时警告用户。语言本身并不绝对需要涵盖这一点。

https://wiki.php.net/rfc/void_return_type#use_of_void_functions_in_expressions

TL;博士

PHP 已经有void个允许在表达式中使用的内置函数,现在更改它将是一个很大的 BC 突破。

最新更新