我发现自己经常做这种事情:
$foo = true;
$foo = $foo && false; // bool(false)
使用按位运算符,可以使用&=
和|=
的简写:
$foo = 1;
$foo &= 0; // int(0)
假设1
和0
上的逐位运算在功能上等效于true
和false
上的布尔运算,我们可以依赖类型转换并执行以下操作:
$foo = true;
$foo &= false; // int(0)
$foo = (bool)$foo; // bool(false)
但这非常难看,并且违背了使用简写赋值语法的目的,因为我们必须使用另一条语句才能将类型恢复为boolean。
我真正想做的是这样的事情:
$foo = true;
$foo &&= false; // bool(false)
但&&=
和||=
显然不是有效的算子。所以,我的问题是——是否有其他一些甜蜜的语法,或者可能有一个模糊的核心函数可以作为替代?对于短如$foo
的变量,只使用$foo = $foo && false
语法并不是什么大不了的事,但具有多维的数组元素和/或对象方法调用可能会使语法变得相当冗长。
在某种程度上,您已经回答了自己的问题:
1和0上的逐位运算在功能上等效于真和假上的布尔运算
请记住,PHP是一种弱类型语言,因此不需要对严格布尔值进行类型转换,因为1
和0
等效于true
和false
(除了严格相等,请参见下文)。
使用您的示例,考虑以下代码:
$foo = true;
$foo &= false;
if (!$foo) {
echo 'Bitwise works!';
}
$bar = true;
$bar = $bar && false;
if (!$bar) {
echo 'Boolean works!';
}
// Output: Bitwise works!Boolean works!
考虑到PHP的隐式类型杂耍、错误的值,除了严格的equatiy,我很难看出&&=
和||=
的这种简写操作在哪里不会产生与&=
和|=
相同的结果。特别是当评估布尔值时。这很可能是PHP中不存在这种人手不足的原因。
更新
一些快速基准测试证明了它们确实是等效的,除了truthy数组/对象:
<?php
$values = array(false, 0, 0.0, "", "0", array(), 12, "string", array(1));
foreach ($values as $value) {
$bit_test = true;
$bit_test &= $value;
$bool_test = true;
$bool_test = $bool_test && false;
if ($bit_test != $bool_test) {
echo 'Difference for: ';
var_dump($value);
}
}
// Output:
// Difference for: array(1) {
// [0]=>
// int(1)
// }
正如Jason所提到的,位运算符将起作用,并且不需要将结果转换回布尔值,因为PHP已经将其值正确地作为布尔值处理。
如果你想要一个不使用逐位运算符的替代方法,为了可读性,或者如果你想要严格相等,你可以使用这个方法:
function OrOp(&$booleanVar, $conditions)
{
$booleanVar = $booleanVar && $conditions;
return $booleanVar;
}
也就是说,你可以改变这个:
$foo = $foo && false;
对此:
OrOp($foo, false);
它还可以在多种条件下工作:
OrOp($foo, $condition1 && $condition2 && $condition3);
Right、&&=
和||=
运算符在PHP中确实缺失,因为位运算符不能用作替换(无强制转换)。
下面是一个您希望返回true
但返回false
:的示例
$a = true;
$a &= 10; // => returns 0 (false) because 1 & 10 = 0
缺少的&&=
运算符将返回true
,因为1 && 10
=true
$a = true;
$a &&= 10; // => $a would be true