PHP的空合并运算符的正确关联性

时间:2016-10-05 13:38:08

标签: php operators null-coalescing-operator associativity

根据PHP文档,空合并运算符import json # we have to parse the output since it no more a dict data = json.loads(response.content) # if `response.content` is a byte string, decode it data = json.loads(response.content.decode('utf-8')) 是右关联的,即

??

相当于

$a ?? $b ?? $c

这有什么意义?开发人员认为它是左关联的还是右关联的?

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

$a ?? ($b ?? $c)

输出:

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"));

2 个答案:

答案 0 :(得分:-1)

我正在考虑性能问题,如果它是左关联的话,你必须多次评估??(如果第一个值是非空的),而只有当它是右关联的时候。比较这两种情况:

(("a" ?? "b") ?? "c") ?? "d"
"a" ?? ("b" ?? ("c" ?? "d"))

在第一行,在解析了第二个(内部)括号?? "b"之后,解析了第一个(外部)括号?? "c"内的值,然后解析了最终的?? "d"??执行了3次。

在第二行,由于"a"不为空,因此不需要解析("b" ?? ("c" ?? "d"))的整个块。 ??只执行一次。

虽然没有解决右侧值,但检查!== null次数可能仍然有用。

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

答案 1 :(得分:-2)

  

这有什么意义?

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

这项工作

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

这是你可能期望三元运算符默认来自C或C ++,但你会错。新的??运算符允许以下替代方法:

这将有效

echo $foo ?? $bar ?? $baz ?? 'default';