2015-08-06 14 views
16

Próbuję zrozumieć poniższy kod, ale jestem zdezorientowany przez użycie operatora &&.
proszę wyjaśnić cel operacji && w poniższym kodzieNiezwykłe użycie && operatora

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

Dzięki za odpowiedź. Działa ............ –

Odpowiedz

15

Tutaj, && działa jako operator zwarcia, jak powiedział @robby.

  • Jeśli zadzwonisz getErrors() $ autoclean będzie prawdą, $ this-> unsetErrorMessages() będzie wykonywany.
  • Jeśli wywołasz getErrors (fałsz), $ autoclean będzie fałszywe, $ this-> unsetErrorMessages() nie zostanie wykonane .

Linia zapewnia nam zachowanie, aby zapobiec domyślny wykonanie dowolnego kodu a także dostarcza nam siłownia w celu zmniejszenia linii kodu jak

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

będzie równoważna

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

@robby to właśnie powiedziałem, zobacz odpowiedź, wspomniałem również twoje imię. Właśnie to wyjaśniłem, aby bursztyn nie mylił się z "jeśli" w przyszłości. –

+9

Coś, co warto zauważyć: Instrukcja if będzie prawdopodobnie postrzegana jako czystszy kod i łatwiej zrozumiała, nawet jeśli jest to 3x tyle linii. Mniejsza liczba linii nie zawsze jest lepsza. –

+0

true @kevin, ale czasami potrzebna jest optymalizacja, jak wtedy, gdy opracowujesz framework lub coś w rodzaju: –

30

Tutaj && pełniące funkcję operatora short-circuit (patrz również przykład kodu here).

  • Jeśli $autoClean ocenia się true, $this->unsetErrorMessages()będzie być wykonywany.
  • Jeśli $autoClean ocenia się false, $this->unsetErrorMessages()nie być wykonywany.

Zastosowanie || zamiast && spowodowałoby odwrócenie tego zachowania.

To samo zachowanie można oczywiście osiągnąć również poprzez dodanie dodatkowej instrukcji if. Czyniąc tak:

  • a && b() może być zapisane jako

    if (a) { 
        b(); 
    } 
    
  • a || b() może być zapisane jako

    if (!a) { 
        b(); 
    } 
    

Chociaż użycie operatorów zwarcia może zmniejszyć liczba linii, może również utrudnić odczyt kodu.

Pod względem prędkości wykonania nie powinno być zauważalnej różnicy.


Aktualizacja

muszę wycofać moje wcześniejsze stwierdzenie o ponieważ żadna zauważalna różnica w szybkości wykonania. Biorąc pod uwagę następujące dwa skrypty testowe, czyli wersja z operatorem zwarcia:

<?php 
    $a = true;                         

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

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

oraz wersja z oświadczeniem if:

<?php 
    $a = true;                         

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

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

Okazuje się, że druga wersja (z if oświadczenie) jest około 40% szybsze (~ 450ms vs. ~ 750ms) na mojej wersji PHP 5.5.9 uruchomiony na Ubuntu 14.04 LTS (64-bitowy).

Wyniki mogą się różnić w zależności od wersji PHP i systemów operacyjnych, ale przynajmniej na moim komputerze konsekwentnie zauważam znaczną różnicę w szybkości realizacji.

+1

Możesz także użyć dosłownego słowa 'lub' oraz' i' np. 'If ((true lub true) and true)' – zanderwar

+0

Zasadniczo działa on na zasadzie shortcircuiting.W przypadku OR (cnd1 || cnd2), jeśli cnd1 == true, spowoduje to zwarcie operacji i nigdy nie przejdzie do cnd2. Podobnie, dla AND sprawdza cnd2 tylko wtedy, gdy cnd1 jest prawdziwe. – Pritam

+3

Coś, co warto odnotować: odpowiednik, jeśli stwierdzenie będzie prawdopodobnie postrzegane jako czystszy kod i łatwiejsze do zrozumienia, mimo że jest to trzykrotnie więcej linii. Mniejsza liczba linii nie zawsze jest lepsza. –