【问题标题】:'AND' vs '&&' as operator'AND' 与 '&&' 作为运算符
【发布时间】:2011-02-17 16:49:05
【问题描述】:

我有一个代码库,其中开发人员决定使用ANDOR 而不是&&||

我知道运算符的优先级存在差异(&&and 之前),但对于给定的框架(准确地说是PrestaShop),这显然不是原因。

您使用的是哪个版本? and 是否比 && 更具可读性?还是没有区别?

【问题讨论】:

  • 请注意,~ 是按位 NOT 运算符,而不是逻辑运算符。 ;-)
  • 是的,我知道。陋习 :) 。有点奇怪的是,PHP中有'and'、'or'和'xor',却没有'not',不是吗?
  • @ts:这里的正确答案是R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/…提供的答案
  • !是逻辑非运算符
  • @chiliNUT 非常正确。这在当时一定是有道理的。看起来潜伏的错误答案在这一点上受到了惩罚:)

标签: php operators operator-precedence


【解决方案1】:

另一个使用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

【讨论】:

    【解决方案2】:

    如果你使用ANDOR,你最终会被这样的东西绊倒:

    $this_one = true;
    $that = false;
    
    $truthiness = $this_one and $that;
    

    想猜猜$truthiness 等于什么?

    如果你说false... bzzzt,对不起,错了!

    上面的$truthiness 的值为true。为什么? =and 有一个 higher precedence。添加括号以显示隐式顺序使这一点更清楚:

    ($truthiness = $this_one) and $that
    

    如果您在第一个代码示例中使用&& 而不是and,它将按预期工作并且是false

    正如下面的 cmets 中所讨论的,这也可以获取正确的值,因为括号的优先级高于 =

    $truthiness = ($this_one and $that)
    

    【讨论】:

    • +1:这应该在 PHP 文档中明确说明,或者 PHP 应该更改并给予这些运算符相同的优先级,或者一劳永逸地弃用 and or。我看到太多人认为他们完全一样,这里的答案更多的是推荐。
    • 实际上,其他语言(例如 Perl 和 Ruby)也有这些变体,具有相同的优先级区分,因此偏离这个标准是不明智的(但对于初学者来说可能会令人费解)通过在 PHP 中使优先级相等。更不用说大量 PHP 应用程序的向后兼容性了。
    • 人们无法阅读某种语言的文档并不会使该语言的决定出错。正如 Mladen 所指出的,Perl 和 Ruby 也使用这些额外的运算符,并且具有相同的优先级。它允许诸如$foo and bar() 之类的构造,这是 if 语句的不错的快捷方式。如果意外行为(来自糟糕的文档,或者没有阅读它)是不使用我们根本不会谈论使用 PHP 的东西的原因。
    • 我花了 3 分钟找到错误的行:$this = true, :( 还有 $truthiness = ($this and $that) 怎么样;对我来说看起来更好:)
    • 我同意 Dmitriy 的观点 - 将布尔评估括在括号中有助于阐明代码的意图。我认为现在存在的运算符及其功能很有价值,并且与其他语言保持一致,理解语言是程序员的工作。
    【解决方案3】:

    让我解释一下“and” - “&&” - “&”之间的区别。

    “&&”和“and”都是逻辑与运算,它们做的事情是一样的,只是运算符的优先级不同。

    运算符的优先级(priority)指定了它将两个表达式“紧密”绑定在一起的程度。例如,在表达式 1 + 5 * 3 中,答案是 16 而不是 18,因为乘法(“*”)运算符的优先级高于加法(“+”)运算符。

    在单个操作中将它们混合在一起,在某些情况下可能会给您带来意想不到的结果 我建议始终使用 &&,但这是您的选择。


    另一方面,“&”是按位与运算。它用于评估和操作整数值中的特定位。

    例如,如果您执行 (14 & 7),则结果将是 6。

    7   = 0111
    14  = 1110
    ------------
        = 0110 == 6
    

    【讨论】:

      【解决方案4】:

      这里有一个小反例:

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

      输出:

      bool(false)
      

      我想说这种错别字更容易导致隐蔽的问题(与=== 的方式大致相同),并且比adn/ro 更不容易被注意到拼写错误将标记为语法错误。我还发现和/或更容易阅读。 FWIW,大多数表达偏好的 PHP 框架(大多数不)指定和/或。我也从未遇到过真正的、非人为的案例。

      【讨论】:

        【解决方案5】:

        由于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
        

        【讨论】:

          【解决方案6】:

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

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

          因此,使用 && 和 ||更安全,因为它们具有最高优先级。在可读性方面,我想说这些运算符足够通用。

          更新:关于 cmets 说这两个操作都返回 false ...好吧,实际上上面的代码没有返回任何内容,我很抱歉模棱两可。澄清一下:第二种情况下的行为取决于如何使用操作的结果。观察运算符的优先级如何在这里发挥作用:

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

          $a === true 的原因是赋值运算符优先于任何逻辑运算符,正如其他答案中已经很好解释的那样。

          【讨论】:

          • 这不是真的,它们都返回假。
          【解决方案7】:

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

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

          【讨论】:

          • 就我个人而言,我认为添加多余的不必要的括号会使阅读变得更加混乱,而不是仅仅拥有你需要的东西。例如,我认为这更容易阅读: if (($i == 0 && $b == 2) || ($c == 3 && $f != 5))
          • 我认为这是我一整天看过的最漂亮的代码。干得好。
          • 由于 PHP 是一种解释性语言,如果您不在代码中使用不必要的空格或新行,它会运行得很快。如果你在编译语言上做同样的事情,它只会花费更多时间来编译,但它不会在运行时生效。我并不是说这样做一次会造成差异,而是在使用 php + javascript 的整个应用程序上都像示例一样编写...加载时间肯定会更长。说明:空格和新行被忽略,但要忽略它们,必须检查它们。这发生在运行时解释语言和编译编译语言时。
          • @JoelBonetR 如果您使用的是 php opcache 或类似的,那么您对加载时间的担忧是无关紧要的。我希望没有人在没有它的情况下运行生产 php 站点...
          • @PeloNZ 所以你可以写脏,因为无论如何它都会被缓存,整个项目在刷新时只需要一秒钟的时间来加载,对吧?代码干净是为了你自己和你的队友,关于时间的问题只是大多数人忽略或根本不知道的一点。
          【解决方案8】:

          &&and 之间的优先级不同(&& 的优先级高于 and),当与三元运算符结合使用时会导致混淆。例如,

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

          将返回一个 字符串

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

          将返回一个布尔值

          【讨论】:

            【解决方案9】:

            根据它的使用方式,它可能是必要的,甚至是方便的。 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;
            

            但在大多数情况下,这似乎更像是一种开发人员的品味,就像我在 CodeIgniter 框架中看到的每一次出现这种情况一样,就像 @Sarfraz 提到的那样。

            【讨论】:

            • 值得注意的是,如果该表达式是更大语句的一部分,则不会忽略“true”。考虑if ($f = false or true) $f = true; 的情况 - 结果将是$f 最终变为真,因为表达式的整体评估结果为真。
            • 不,您只是稍后覆盖了变量。表达式仍然评估为 false,然后在下一行用 true 覆盖它。
            • 其实他是对的。首先,$f 被分配为 false - 但条件评估为 true,因此 $f 被覆盖。如果条件评估为假,$f 将永远不会被覆盖。
            • 建议开发人员应该遵循自己的口味是荒谬的。忘记另一个开发人员试图维护相同代码的噩梦吧,编写代码本身的开发人员在编写的任何代码中都会犯语义错误,因为他/她更喜欢and 而不是&&,其中and 按预期工作只有某些情况,&& 在所有情况下都能按预期工作。
            【解决方案10】:

            您使用的是哪个版本?

            如果我正在为其编写代码的特定代码库的编码标准指定应使用哪个运算符,我将肯定使用它。如果没有,并且代码 dictates 应该使用(不经常,可以很容易地解决),那么我会使用它。否则,可能 &&.

            'and' 比 '&&' 更易读吗?

            它对你来说更具可读性。答案是是和否,这取决于许多因素,包括操作员周围的代码以及阅读它的人!

            ||有~区别吗?

            是的。请参阅 logical operators 以获取 ||bitwise operators 以获取 ~

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-07-18
              • 1970-01-01
              • 2013-07-03
              • 1970-01-01
              • 2015-02-26
              • 1970-01-01
              相关资源
              最近更新 更多