提问人:miken32 提问时间:10/7/2021 最后编辑:LazyOnemiken32 更新时间:10/6/2022 访问量:15497
PhpStorm 检查中的“添加 #[Pure] 属性”检查是做什么的?
What is the "Add #[Pure] attribute" inspection in PhpStorm checking for?
问:
我在 Laravel 项目中有一个非常简单的类。两个方法,它们都返回一个由方法部分填充的简单数组,但 IDE 以不同的方式处理它们。FormRequest
<?php
namespace App\Http\Requests;
class VerifyPhoneNumber extends FormRequest {
use Support\ValidatesPhoneNumbers;
public function authorize(): bool {
return true;
}
public function rules(): array {
return [
"phone_number" => $this->getPhoneNumberRules(),
"verify_code" => ["required", "numeric", "max:999999"],
];
}
public function messages(): array {
return [
"phone_number.regex" => $this->getPhoneNumberMessage(),
];
}
}
以及最基本的特质方法:
<?php
namespace App\Http\Requests\Support;
trait ValidatesPhoneNumbers {
protected function getPhoneNumberMessage(): string {
return __("Some localized error message");
}
protected function getPhoneNumberRules(): array {
return ["regex:/^\+?1?[2-9][0-9]{5,14}$/", "max:16"];
}
}
令我感到困惑的是,IDE检查抱怨我应该将属性添加到方法中,而不是方法中。JetBrains\PhpStorm\Pure
rules()
messages()
类定义中的注释说:
该属性标记对程序状态没有影响的函数或函数执行后使用的传递参数。 这意味着,如果之后未在代码中使用执行结果,则可以安全地删除解析为此类函数的函数调用。
这并没有真正给我任何线索,为什么它以不同的方式对待这两种方法。如果我正确理解了第二句话,当“纯”方法的结果未使用时,IDE 会将该方法的使用标记为未使用并建议将其删除。
用于确定何时需要此属性的逻辑是什么?
答:
如果一个函数只依赖于其他纯函数,那么它也是纯函数。因为只返回一个固定的数组,所以它是纯的,所以也是纯的。getPhoneNumberRules()
rules()
但是 calls ,它调用的函数可以在位置状态更改时返回不同的本地化消息,因此它不是纯的。messages()
getPhoneNumberMessage()
__()
评论
该方法具有固定(最好说“无副作用”)结果 - 它仅使用固定值。当然,它从特征调用,但它也返回固定数组(始终相同)。它不会在其他任何位置(内部状态或外部存储)进行更改。rules()
getPhoneNumberRules()
该方法从特征中调用一个方法,该特征调用以获取已翻译的消息...它可能来自不同的源(数据库、文件),因此如果存储(文件/数据库)不可读,则可能会引发异常。IDE 不确定是否对文件/数据库进行了更改 -- 它没有注释为纯文件,并且 PhpStorm 无法从它使用的方法中做出这样的决定。messages()
__()
__()
附言如果此检查惹恼了您(我可以理解),那么我建议您忽略此类检查并将其在 PhpStorm 设置中的严重性降低为“不突出显示,仅修复”(Settings (Preferences on macOS) | Editor | Inspections | PHP | Attributes | '#[Pure]' attribute can be added
)
评论
__()
__()
__()
__()
#Pure
在 PhpStorm 中,与其他语言/文学中的“纯函数”含义并不完全匹配。这就是为什么您可以找到将其重命名为 youtrack.jetbrains.com/issue/WI-56211 的建议。#[NoSideEffect
将此属性用于不产生任何副作用的函数。所有这些 PHP 内部函数都已经在 PhpStorm 中标记了。
#[Pure] function compare(Foo $a, Foo $b): int { return $a->a <=> $b->b; }
来源: https://github.com/JetBrains/phpstorm-attributes#pure
由于这个函数只在它自己做一些事情,所以它可以被称为#[Pure]函数,所以你通过PhpStorm知道这一点。
暂时忘记副作用。
纯函数是保证在使用相同参数调用时始终给出相同结果的函数。
如果您的应用程序调用它,它将得到特定的结果。然后,其他一些代码可能会更改应用程序区域设置,下次以完全相同的方式调用时(即不带参数),它可能会返回不同的结果,因为 or 函数会检查某些全局状态(区域设置)以决定要返回哪个字符串。$verifyPhoneNumberRequest->rules()
$verifyPhoneNumberRequest->rules()
__()
trans()
纯函数仅依赖于它们的直接输入参数,而不依赖于某些可能在其他地方被修改过也可能没有被修改的外部状态。
纯函数的另一个标准是它们不修改非局部状态。完全有可能将整个数据库放在 getUsername() 方法中(或者导致破坏性较小但对调试修改的痛苦)。但是,如果该方法被标记为纯方法并被批准为纯方法,则可以保证不会发生这种情况。
评论