PHP'的右结合性;s零合并算子

PHP'的右结合性;s零合并算子,php,operators,null-coalescing-operator,associativity,Php,Operators,Null Coalescing Operator,Associativity,根据PHP文档,空合并操作符?是右关联的,即 $a ?? $b ?? $c 相当于 $a ?? ($b ?? $c) 这有什么意义?对于开发人员来说,它是左关联还是右关联有什么区别 对于那些认为它将调用更少函数的人来说,这是不正确的,因为根据我的测试,如果左操作数不为null,则不会计算右操作数: function f(string $a) : string { echo "f($a)\n"; return $a; } var_dump(f("a") ?? f("b") ??

根据PHP文档,空合并操作符
是右关联的,即

$a ?? $b ?? $c
相当于

$a ?? ($b ?? $c)
这有什么意义?对于开发人员来说,它是左关联还是右关联有什么区别

对于那些认为它将调用更少函数的人来说,这是不正确的,因为根据我的测试,如果左操作数不为null,则不会计算右操作数:

function f(string $a) : string {
    echo "f($a)\n";
    return $a;
}
var_dump(f("a") ?? f("b") ?? f("c") ?? f("d"));
echo "===\n";
var_dump(((f("a") ?? f("b")) ?? f("c")) ?? f("d"));
输出:

f(a)
string(1) "a"
===
f(a)
string(1) "a"
这有什么意义

与三元运算符(左关联)相比,右关联的空合并运算符允许堆叠。例如:

这行不通

echo isset($foo) ? $foo :
     isset($bar) ? $bar :
     isset($baz) ? $baz :
     'default';
echo $foo ?? $bar ?? $baz ?? 'default';
<>这是你可能期望三元操作符默认工作于C或C++,但是你错了。新的
??
操作员允许以下替代方案:

这将起作用

echo isset($foo) ? $foo :
     isset($bar) ? $bar :
     isset($baz) ? $baz :
     'default';
echo $foo ?? $bar ?? $baz ?? 'default';
这有什么意义

与三元运算符(左关联)相比,右关联的空合并运算符允许堆叠。例如:

这行不通

echo isset($foo) ? $foo :
     isset($bar) ? $bar :
     isset($baz) ? $baz :
     'default';
echo $foo ?? $bar ?? $baz ?? 'default';
<>这是你可能期望三元操作符默认工作于C或C++,但是你错了。新的
??
操作员允许以下替代方案:

这将起作用

echo isset($foo) ? $foo :
     isset($bar) ? $bar :
     isset($baz) ? $baz :
     'default';
echo $foo ?? $bar ?? $baz ?? 'default';

我考虑的是性能问题,如果它是左关联的,则必须多次计算
??
(如果第一个值为非null),而如果它是右关联的,则必须计算一次。比较这两种情况:

(("a" ?? "b") ?? "c") ?? "d"
"a" ?? ("b" ?? ("c" ?? "d"))
在第一行中,在第二个(内)括号后
??“b”
已解析,第一个(外)括号内的值
??“c”
被解析,那么最终的
??“d”
已解决<代码>??执行3次

在第二行,因为
“a”
不是空的,所以
(“b”?(“c”?“d”)
的整个块不需要解析<代码>??仅执行一次

尽管未解析右侧值,但请检查
!==空
更少的次数可能仍然是有益的


(不过,我想知道这是否是唯一的原因?

我在考虑性能问题,如果第一个值是左关联的,则必须多次计算
??
,如果它是右关联的,则必须计算一次。比较这两种情况:

(("a" ?? "b") ?? "c") ?? "d"
"a" ?? ("b" ?? ("c" ?? "d"))
在第一行中,在第二个(内)括号后
??“b”
已解析,第一个(外)括号内的值
??“c”
被解析,那么最终的
??“d”
已解决<代码>??执行3次

在第二行,因为
“a”
不是空的,所以
(“b”?(“c”?“d”)
的整个块不需要解析<代码>??仅执行一次

尽管未解析右侧值,但请检查
!==空
更少的次数可能仍然是有益的


(不过,我想知道这是否是唯一的原因?

如果它是左关联的,即
($foo???$bar)?$baz)?”默认值“
?@pemapmoder没有错,只是更简洁/语法上的糖分。那么你就没有回答这个问题了。“更干净的/语法上的甜言蜜语”似乎纯粹是基于观点的。@Pemapmoder你不必喜欢这个答案,但事实上,它就是答案。您询问了重要性,并提供了重要性。OP了解
的作用,并且与
?:
相反,它易于堆叠。问题是
的左关联性和右关联性是否有实际区别。如果是左关联性,即
(($foo???$bar)??$baz)?,又有什么错呢默认值“
?@pemapmoder没有错,只是更简洁/语法上的糖分。那么你就没有回答这个问题了。“更干净的/语法上的甜言蜜语”似乎纯粹是基于观点的。@Pemapmoder你不必喜欢这个答案,但事实上,它就是答案。您询问了重要性,并提供了重要性。OP了解
的作用,并且与
?:
相反,它易于堆叠。问题是
??
的左关联性与右关联性是否有任何实际区别。如果
$a
$b
$c
是函数,那么作为一个简单的例子,如果是左关联或右关联,则会导致完全不同的执行。如果在
之外使用不同的运算符,则根据代码执行的“关联性”完全不同,会发生相同的情况。@Rizier123现在会这样吗?FWIW,我想不出任何一种情况,在这种情况下,左关联的
??
运算符与堆叠的
??
运算符组合会产生不同的结果。它似乎只与内部短路有关;i、 e.左关联
运算符总是计算所有堆叠表达式(即使不是它们的操作数),而不是尽快返回。不过,您可能会发现将它与其他运算符组合在一起时会出现不同的行为。我要添加“运算符优先级和关联性指定分组,但它们不指定分组的执行顺序。”如果
$a
$b
$c
将是函数,那么这将导致完全不同的执行,如果它是左关联或右关联的,作为一个简单的示例。如果在
之外使用不同的运算符,则根据代码执行的“关联性”完全不同,会发生相同的情况。@Rizier123现在会这样吗?FWIW,我想不出任何一种情况,在这种情况下,左关联的
??
运算符与堆叠的
??
运算符组合会产生不同的结果。它似乎只与内部事务相关