gpt4 book ai didi

php - JS 与 PHP : assignment operator precedence when used with logical-or

转载 作者:IT王子 更新时间:2023-10-29 00:18:09 25 4
gpt4 key购买 nike

(PHP有||OR。JS只有||。)

JS. 根据MDN || 的优先级高于 =。所以这是行不通的:

a || a = 1;

因为它被评估为:

(a || a) = 1;

这会导致“分配中的左侧无效”。我明白那个。这是有道理的。

PHP。 根据 PHP.net它对 PHP 的作用相同:||= 之前。但是,我一直使用它:

$a || $a = 1;

为什么它在 PHP 中工作?最重要的是:PHP 的 OR 的优先级低于 =,因此它们不应该做同样的事情:

$a || $a = 1;
$a OR $a = 1;

但他们确实... https://3v4l.org/UWXMd

我认为 JS 的 || 是根据 MDN 的表工作的,而 PHP 的 OR 的工作方式类似于 PHP 的表,但是 PHP 的 || 应该是'不像它那样工作。

这是另一个奇怪的 PHP 怪癖吗?

手册中还提到了这一点:

Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.

优先级表指示 PHP 应该计算 (!$a) = foo(),这没有任何意义并且应该失败,但是 PHP 将它计算为 !($a = foo( )),因为它喜欢异常。

后续问题:您认为 if ( $d = $c && $e = $b && $f = $a ) 会怎样? https://3v4l.org/3P2hN我不明白...我确实理解第二种和第三种情况(使用 ),只是不理解第一种情况。

最佳答案

根据 zend_language_parser.y代码被解析为等同于 $a || ($a = 1)$a or ($a = 1) 在每种情况下,分别。

正如 melpomene 总结的那样,赋值产生式不是表达式上的中缀二元运算符;相反,赋值运算符是受限产生式,其中左侧必须变量产生式。

根据 borrowed quote :

Thus PHP parses the expression in the only possible way..

关于优先级的文档正确..它适用。


因此 $a || $a = 1 遵循(反转)产生式:

variable "||" variable "=" expr
variable "||" expr_without_variable
expr "||" expr
expr

!$a = foo() 的情况类似,在遵循(反向)产生式后被解析为 !($a = foo()):

"!" variable "=" expr
"!" expr_without_variable
"!" expr
expr

现在,$d = $c && $e = $b && $f = $a 怎么样?它被解析为($d = $c) && ..,即使&& 确实有一个优先级高于赋值。它实际上被解析为$d = ($c && ($e = ..)) 等等,由精明的读者完成。

虽然可能不会随便注意到,但这种差异能够产生不同的结果:

$a = (($c = 1) && ($d = 0));
var_dump($a, $c, $d); // => false, 1, 0

$b = ($e = 1 && $f = 0); // => $b = ($e = (1 && ($f = 0)));
var_dump($b, $e, $f); // => false, false, 0

因此,在将赋值运算符与优先级更高的运算符混合使用时,通常应使用括号,尤其是当其结果可能不明确时。

尽管这最初看起来不一致,但它是一个定义明确的语法 - 但技术细节隐藏在一些相当外行的文档之后;并且这些规则与其他类似 C 语法的语言中的规则略有不同。文档中缺少官方 EBNF 也于事无补。


尽管有解析细节,$a || $a = .. 代码( 是有效且定义明确的语法)从评估的角度来看应该保持定义明确,因为“或”的左侧必须出现在由于guaranteed short-circuiting .


相比之下,在 JavaScript 中,a || a = 1 被解析为 (a || a) = 1 - 这在语法上也是“有效”代码 - 根据 ECMAScript Grammar Rules .然而,一个|| a 不会产生有效的引用规范类型,因此会抛出一个运行时 ReferenceError。

关于php - JS 与 PHP : assignment operator precedence when used with logical-or,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32672016/

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