'AND'和'&&'作为运算符的区别

342

我有一个代码库,开发者决定使用 ANDOR 代替 &&||

我知道运算符优先级有所不同(&&and 前面),但在给定的框架(具体来说是PrestaShop)中,这显然不是原因。

你们正在使用哪个版本?使用 and 比使用 && 更易读吗?还是没有区别?


2
是的,我知道。这是个坏习惯 :) 。在PHP中有'and'、'or'和'xor',但没有'not',这有点奇怪,不是吗? - ts.
4
!是逻辑非运算符。 - Razor Storm
1
@doublejosh,你的评论并没有帮助任何人,因为谁知道你在引用哪个答案,而且提问者可能已经改变了答案?哪个答案是(或曾经)误导性的? - chiliNUT
2
@chiliNUT非常正确。当时这样做肯定是有道理的。看起来那个错误答案已经被惩罚了 :) - doublejosh
1
@doublejosh 很快就回复了一年前的评论,谢谢! - chiliNUT
显示剩余3条评论
10个回答

728
如果你使用 ANDOR,最终你会被这样的东西绊倒:
$this_one = true;
$that = false;

$truthiness = $this_one and $that;

希望你能猜出$truthiness等于多少?

如果你猜测是false,答错了!

$truthiness的值为true。为什么呢?因为=优先级高于and。加上括号可以更清楚地显示隐含的顺序:

($truthiness = $this_one) and $that

如果您在第一个代码示例中使用&&而不是and,它将按预期工作并返回false
正如下面的评论中所讨论的那样,这也可以用于获取正确的值,因为括号比=具有更高的优先级。
$truthiness = ($this_one and $that)

162
在PHP文档中应明确指出这一点,或者PHP应该改变并给予这些运算符相同的优先级,或者干脆废弃'and'和'or'。我看到太多人认为它们是完全相同的东西,这里的答案更像是见证。 - Marco Demaio
12
实际上,其他语言(例如Perl和Ruby)也有这些具有相同优先级区别的变体,因此,在PHP中使优先级相等并不明智(尽管对于初学者来说可能很困惑)。更不用说数以万计的PHP应用程序的向后兼容性了。 - Mladen Jablanović
26
人们无法阅读语言文档并不会使该语言的决策错误。正如Mladen所指出的,Perl和Ruby也使用这些额外操作符,并且具有相同的优先级。它允许构造像$foo and bar()这样的东西,这是if语句的不错快捷方式。如果由于糟糕的文档或未阅读文档而导致意外行为成为不使用某物的原因,那么我们根本就不会谈论使用PHP。 - Altreus
6
我同意Dmitriy的观点 - 在布尔运算中加上括号有助于澄清代码的意图。我认为现在操作符和它们的功能很有价值,并且与其他编程语言保持一致,这是程序员理解语言的任务。 - Jon z
3
以前我避免使用 && 和 ||,因为我错误地认为它们是遗留问题,并且它们读起来不像“英语”,但它们几乎总是我想要的。 - zzapper
显示剩余11条评论

48

根据它的使用方式,可能需要甚至很方便。

http://php.net/manual/en/language.operators.logical.php
// "||" has a greater precedence than "or"

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;

但在大多数情况下,这似乎更像是开发人员的口味问题,就像@ Sarfraz提到的CodeIgniter框架中我见过的每个实例一样。


2
值得注意的是,如果该表达式是更大语句的一部分,“true”就不会被忽略。考虑这种情况 if ($f = false or true) $f = true; - 最终结果是 $f 变成了 true,因为整个表达式总体上是 true。 - Chris Browne
1
不,你只是在后面覆盖了变量。表达式仍然评估为false,然后你在下一行将其覆盖为true。 - r3wt
3
实际上,他是正确的。首先,$f被赋值为false - 但条件评估为true,因此$f被覆盖。如果条件评估为false,则无论如何$f都不会被覆盖。 - ahouse101
建议开发人员应该遵循自己的口味是荒谬的。忘记另一个开发人员试图维护相同代码的噩梦,编写代码本身的开发人员将在任何编写的代码中犯语义错误,因为他/她更喜欢使用 and 而不是 &&,其中 and 仅在某些情况下按预期工作,而 && 在所有情况下都按预期工作。 - ADTC

16

and 的优先级低于 =,因此你可以在条件赋值中使用它:

if ($var = true && false) // Compare true with false and assign to $var
if ($var = true and false) // Assign true to $var and compare $var to false

13

为了安全起见,我总是加括号并将比较分开。这样,我就不必依赖运算符优先级:

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )

34
个人认为添加多余的括号会使阅读更加困难,相比仅包含必要的括号。例如,我认为以下写法更易于阅读:if (($i == 0 && $b == 2) || ($c == 3 && $f != 5))。 - rooby
4
我认为这是我今天看过的最漂亮的代码。做得好! - rm-vanda
由于PHP是一种解释性语言,如果您的代码中不使用不必要的空格或换行符,则它将运行得很快。如果在编译语言上执行相同操作,只会导致编译时间更长,但不会对运行时产生影响。我的意思不是说这样做一次就会有所不同,但是在整个应用程序中,如果同时使用像示例中编写的php + javascript,加载时间肯定会更长。说明:空格和换行符被忽略,但要忽略它们,必须进行检查。这在解释性语言上发生,在编译语言上则在编译时发生。 - JoelBonetR
1
@JoelBonetR 如果你正在使用PHP Opcache或类似的东西,那么你对于加载时间的担忧是不必要的。我希望没有人在没有它的情况下运行生产PHP网站... - PeloNZ
@PeloNZ,你可以写脏代码,因为它最终会被缓存,而整个项目在刷新时只需要多加载一秒钟的时间,是吗?编写干净的代码是为了你自己和团队成员着想,关注时间问题只是大多数人忽略或根本不知道的一个点。 - JoelBonetR
空格只是为了可读性,对加载时间几乎没有影响。你是否会将所有JS代码都写成压缩形式,以便在运行JS编译器时节省时间? - PeloNZ

12

&&and 的优先级不同(&& 的优先级高于 and),这在与三元运算符结合时容易引起混淆。例如:

$predA && $predB ? "foo" : "bar"

将返回一个字符串,而

$predA and $predB ? "foo" : "bar"

将返回一个布尔值


3
让我来解释一下“and”、“&&”和“&”之间的区别。
“&&”和“and”都是逻辑“AND”操作,它们执行相同的操作,但运算符优先级不同。运算符优先级指定了运算符如何将两个表达式紧密地绑定在一起。例如,在表达式1 + 5 * 3中,答案是16而不是18,因为乘法(“*”)运算符的优先级高于加法(“+”)运算符。
在单个操作中混合使用它们可能会在某些情况下给您带来意外的结果。我建议始终使用“&&”,但这是您的选择。
另一方面,“&”是按位“AND”操作。它用于评估和操作整数值内的特定位。
例如,如果您执行(14&7),则结果将为6。
7   = 0111
14  = 1110
------------
    = 0110 == 6

2

另一个很好的例子是使用if语句而不涉及=赋值操作。

if (true || true && false); // is the same as:
if (true || (true && false)); // TRUE

并且

if (true || true AND false); // is the same as:
if ((true || true) && false); // FALSE

因为 AND 的优先级较低,而 || 的优先级较高。
true, false, falsetrue, true, false 的情况下是不同的。 请参见 https://ideone.com/lsqovs,其中有一个详细的示例。

1
你使用的是哪个版本?
如果我编写代码的特定代码库的编码标准指定了应该使用哪个运算符,我肯定会使用那个。如果没有,而代码规定了应该使用哪个(不经常出现,可以轻松解决),那么我会使用那个。否则,可能会使用“&&”。
“and”比“&&”更可读吗?
这取决于许多因素,包括运算符周围的代码和阅读它的人!对你来说更可读吗?答案是有时候是,有时候不是。 || 和 ~ 有区别吗?
有。请参见逻辑运算符以获取“||”,并参见位运算符以获取“~”。

0

这里有一个简单的计数器示例:

$a = true;
$b = true;
$c = $a & $b;
var_dump(true === $c);

输出:

bool(false)

我认为这种打字错误更容易导致隐蔽的问题(就像===一样),而且比adn/ro打字错误更不容易被注意到,后者会标记为语法错误。我也发现使用 and/or 更容易阅读。值得一提的是,大多数表达偏好的 PHP 框架(大多数没有)都指定了 and/or。我也从未遇到过一个真正的、非人为制造的情况,在这种情况下它会有所影响。


0

我想这是个品味问题,尽管(错误地)混淆它们可能会导致一些不良行为:

true && false || false; // returns false

true and false || false; // returns true

因此,使用&&和||更加安全,因为它们具有最高的优先级。就可读性而言,我认为这些操作符是足够通用的。
更新:关于评论中提到的两个操作都返回false......实际上上面的代码并没有返回任何东西,对于这种歧义我很抱歉。要澄清的是:第二种情况的行为取决于如何使用操作的结果。观察操作符的优先级在这里起作用:
var_dump(true and false || false); // bool(false)

$a = true and false || false; var_dump($a); // bool(true)

$a === true的原因是赋值运算符比任何逻辑运算符都具有优先级,这已经在其他答案中非常好地解释了。


17
这不是真的,它们都返回false。 - Jay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接