【问题标题】:Unusual use of && operator [duplicate]&& 运算符的不寻常使用[重复]
【发布时间】:2015-10-29 02:48:12
【问题描述】:

我试图理解下面的代码,但我对 && 运算符的使用感到困惑。
请在下面的代码中说明&&操作的目的

function getErrors($autoClean=TRUE) {
     $retVal = $this->getErrorMessages();
     $autoClean && $this->unsetErrorMessages();
     return $retVal;
}

【问题讨论】:

  • 感谢您的回复。它工作............

标签: php operators


【解决方案1】:

这里,&& 充当short-circuit 运算符(另请参见代码示例here)。

  • 如果$autoClean 评估为true$this->unsetErrorMessages() 被执行。
  • 如果 $autoClean 计算结果为 false$this->unsetErrorMessages() 不会被执行。

使用|| 而不是&& 会逆转这种行为。

同样的行为显然也可以通过添加一个额外的if 语句来实现。这样做:

  • a && b()可以改写为

    if (a) {
        b();
    }
    
  • a || b()可以改写为

    if (!a) {
        b();
    }
    

虽然使用短路运算符可以减少行数,但也会使代码更难阅读。

就执行速度而言,应该没有明显差异。


更新

我不得不撤回我之前关于执行速度没有明显差异的声明。给定以下两个测试脚本,即带有短路运算符的版本:

<?php
    $a = true;                                                                                                   

    function b() { global $a; $a = !$a; }

    for ($i = 0; $i < 10000000; $i++) {
        $a && b();
    }
?>

还有一个带有if 声明的版本:

<?php
    $a = true;                                                                                                   

    function b() { global $a; $a = !$a; }

    for ($i = 0; $i < 10000000; $i++) {
        if($a) { b(); }
    }
?>

事实证明,在我在 Ubuntu 14.04 LTS 上运行的 PHP 5.5.9 版本上,第二个版本(带有 if 语句)快了大约 40%(~450ms vs. ~750ms) (64 位)。

不同的 PHP 版本和操作系统的结果可能会有所不同,但至少在我的机器上,我始终注意到执行速度存在显着差异。

【讨论】:

  • 你也可以使用字面意思orand例如if ((true or true) and true)
  • 基本上它的工作原理是短路。在OR(cnd1 || cnd2)的情况下,如果cnd1 == true,它将短路操作并且永远不会对cnd2进行操作。同样,对于 AND,它仅在 cnd1 为真时才检查 cnd2。
  • 需要注意的一点是:等效的 if 语句可能会被视为更简洁的代码并且更容易理解,尽管它的行数是原来的 3 倍。行数越少并不总是越好。
  • 很好的答案。 amber,这也是someStatement() or die();模式you may see elsewhere in PHP背后的解释。
  • 从内部的角度来看,第一个需要隐式布尔转换 [在第二个操作数上] 和一个 AND 操作,这在仅执行 if ($a) { … } 时不需要,这是第一个代码比较慢。
【解决方案2】:

这里,&amp;&amp; 充当了 @robby 所说的短路运算符。

  • 如果您调用 getErrors(),$autoclean 将为 true,$this->unsetErrorMessages() 将为 执行。
  • 如果调用 getErrors(false),$autoclean 会为 false,$this->unsetErrorMessages() 不会 执行。

该行为我们提供了一种防止默认执行​​任何代码的行为 并且还为我们提供了减少代码行的便利 作为

$autoClean && $this->unsetErrorMessages();

将等同于

if($autoClean){
   $this->unsetErrorMessages();
}

【讨论】:

  • 需要注意的一点是:if 语句可能会被视为更简洁的代码并且更容易理解,尽管它的行数是原来的 3 倍。行数越少并不总是越好。
  • @AshwaniShukla 很公平,我主要习惯于编译语言。至少,对不熟悉该语言习语的人来说,评论会有所帮助。
  • @AshwaniShukla 这个案例与优化无关,充其量只是混淆(而且很可能是常见的愚蠢行为)。
  • @AshwaniShukla 你几乎无法优化 PHP 代码,因为 PHP 自己在后台优化了很多。
  • 我怀疑大多数编译器会在这两个语句之间产生差异,并且我严重怀疑差异是否会导致速度的明显提高。无论哪种方式,我认为事后猜测编译器(或解释器,ftm)对于琐碎的事情不是一个好主意。
猜你喜欢
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
相关资源
最近更新 更多