ตัวดำเนินการเชิงตรรกะ, || หรือหรือ?


105

ฉันจำได้ว่าอ่านย้อนหลังเกี่ยวกับตัวดำเนินการเชิงตรรกะในกรณีของการORใช้งาน||นั้นดีกว่าor(หรือในทางกลับกัน)

ฉันต้องใช้สิ่งนี้ในโปรเจ็กต์ของฉันเมื่อมันกลับมาหาฉัน แต่ฉันจำไม่ได้ว่ามีการแนะนำตัวดำเนินการใดหรือเป็นจริง

ไหนดีกว่ากันและทำไม?

คำตอบ:


140

ไม่มี "ดี" ||แต่คนทั่วไปมากขึ้นคือ พวกเขามีลำดับความสำคัญที่แตกต่างกันและ||จะทำงานอย่างที่คาดหวังตามปกติ

ดูเพิ่มเติม: ตัวดำเนินการเชิงตรรกะ ( ตัวอย่างต่อไปนี้นำมาจากที่นั่น ):

// 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;

11
และ$e = true || $x = 'foo'จะไม่กำหนด$xเนื่องจากการลัดวงจรไม่ใช่เพราะมีความสำคัญสูงกว่า
Matt Kieran

1
นอกจากนี้ยังเป็นที่น่าสังเกตว่าสิ่งเหล่านี้จะส่งคืนค่าบูลีนเสมอซึ่งแตกต่างจากภาษาอื่น ๆ ที่ส่งคืนค่าสุดท้ายที่ตรวจสอบ ดังนั้นใน PHP (27 || 0) ผลตอบแทนที่แท้จริงไม่ได้อยู่ที่ 27
TextGeek

@TextGeek "เหล่านี้"? 27 or 0คืนให้27ฉัน
Jānis Elmeris

@ Jānis Elmeris - คุณถูกต้องฉันควรจะอ้างถึง "||" เท่านั้น กรณี.
TextGeek

2
@TextGeek จริงๆแล้วคุณคิดถูกแล้วที่orส่งคืนบูลีนด้วย ความสำคัญของมันต่ำมากจนบางครั้งดูเหมือนทำอย่างอื่น :) print 27 or 0จะพิมพ์27เพราะorเกิดขึ้นหลังจากที่ print 27BTW, echoไม่ได้หลงกล - เอาท์พุทหากว่าecho 27 or 0 1
Jānis Elmeris

43

ใช้เพื่อวัตถุประสงค์ที่แตกต่างกันและในความเป็นจริงมีลำดับความสำคัญของตัวดำเนินการที่แตกต่างกัน ตัวดำเนินการ&&และ||มีไว้สำหรับเงื่อนไขบูลีนในขณะที่andและorมีไว้สำหรับโฟลว์ควบคุม

ตัวอย่างเช่นต่อไปนี้เป็นเงื่อนไขบูลีน:

if ($foo == $bar && $baz != $quxx) {

สิ่งนี้แตกต่างจากขั้นตอนการควบคุม:

doSomething() or die();

die()ฟังก์ชันจะถูกเรียกว่าdoSomething()จะกลับมาfalseหรือnull? เกิดอะไรขึ้นถ้าdoSomething()คืนtrueหรือไม่มีอะไร?
giannis christofakis

5
doSomething()ได้รับการประเมินเป็นบูลีน ถ้าจะส่งกลับค่า PHP พิจารณา truthy ( trueสตริงไม่ว่างเปล่า ฯลฯ ) die()ก็จะไม่โทร
Matthew Ratzloff

23

ความแตกต่างระหว่างตามลำดับ || และ OR และ && และ AND เป็นลำดับความสำคัญของตัวดำเนินการ :

$bool = FALSE || TRUE;

  • ตีความว่า ($bool = (FALSE || TRUE))
  • มูลค่าของ$boolคือTRUE

$bool = FALSE OR TRUE;

  • ตีความว่า (($bool = FALSE) OR TRUE)
  • มูลค่าของ$boolคือFALSE

$bool = TRUE && FALSE;

  • ตีความว่า ($bool = (TRUE && FALSE))
  • มูลค่าของ$boolคือFALSE

$bool = TRUE AND FALSE;

  • ตีความว่า (($bool = TRUE) AND FALSE)
  • มูลค่าของ$boolคือTRUE

5

ที่มา: http://wallstreetdeveloper.com/php-logical-operators/

นี่คือโค้ดตัวอย่างสำหรับการทำงานกับตัวดำเนินการเชิงตรรกะ:

<html>

<head>
    <title>Logical</title>
</head>

<body>
    <?php
        $a = 10;
        $b = 20;
        if ($a>$b)
        {
            echo " A is Greater";
        }
        elseif ($a<$b)
        {
            echo " A is lesser";
        }
        else
        {
             echo "A and B are equal";
        }
    ?>
    <?php
        $c = 30;
        $d = 40;
        //if (($a<$c) AND ($b<$d))
        if (($a<$c) && ($b<$d))
        {
            echo "A and B are larger";
        }
        if (isset($d))
            $d = 100;
        echo $d;
        unset($d);
    ?>
    <?php
        $var1 = 2;
        switch($var1)
        {
            case 1:  echo "var1 is 1";
                     break;
            case 2:  echo "var1 is 2";
                     break;
            case 3:  echo "var1 is 3";
                     break;
            default: echo "var1 is unknown";
        }
    ?>
</body>
</html>

ลิงค์เสีย
Peter Mortensen

2

ฉันรู้ว่ามันเป็นหัวข้อเก่า แต่ก็ยัง ฉันเพิ่งพบปัญหาในรหัสที่ฉันกำลังแก้ไขจุดบกพร่องในที่ทำงานและอาจมีใครบางคนมีปัญหาคล้ายกัน ...

สมมติว่าโค้ดมีลักษณะดังนี้:

$positions = $this->positions() || [];

คุณจะคาดหวัง (ตามที่คุณคุ้นเคยจากเช่น javascript) ว่าเมื่อ $ this-> position () ส่งคืนเท็จหรือ null ตำแหน่ง $ จะเป็นอาร์เรย์ว่าง แต่มันไม่ใช่ ค่าเป็น TRUE หรือ FALSE ขึ้นอยู่กับสิ่งที่ $ this-> position () ส่งกลับ

หากคุณต้องการรับค่า $ this-> position () หรืออาร์เรย์ว่างคุณต้องใช้:

$positions = $this->positions() or [];

แก้ไข:

ตัวอย่างข้างต้นไม่ได้ผลตามที่ตั้งใจไว้ แต่ความจริงก็เป็นเช่นนั้น||และorไม่เหมือนกัน ... ลองทำดังนี้

<?php

function returnEmpty()
{
  //return "string";
  //return [1];
  return null;
}

$first = returnEmpty() || [];
$second = returnEmpty() or [];
$third = returnEmpty() ?: [];

var_dump($first);
var_dump($second);
var_dump($third);
echo "\n";

นี่คือผลลัพธ์:

bool(false)
NULL
array(0) {
}

ดังนั้นตัวเลือกที่สาม?:เป็นวิธีแก้ปัญหาที่ถูกต้องเมื่อคุณต้องการตั้งค่าที่ส่งคืนหรืออาร์เรย์ว่าง

$positions = $this->positions() ?: [];

ทดสอบด้วย PHP 7.2.1


เป็นคำตอบที่ไม่ถูกต้องตัวอย่างที่สองใช้งานได้เหมือนกับคำตอบแรก
WayFarer

@WayFarer ดีมันไม่ถูกต้อง (มีปัญหา) แต่คุณก็ผิดเหมือนกัน (|| และหรือไม่เหมือนกัน) - ดูการแก้ไขของฉัน
Zdeněk

ขวาตัวดำเนินการ || และ 'หรือ' มีลำดับความสำคัญแตกต่างกันดังนั้นตัวอย่างที่สองของคุณจึงทำงานเป็น: (($ second = returnEmpty ()) หรือ []); ดังนั้นคำตอบสำหรับคำถามเดิมคือ || ดีกว่าใช้เสมอจนกว่าคุณจะเข้าใจจริงๆว่าทำไมคุณถึงต้องการใช้ "หรือ"
WayFarer

1
$positions = $this->positions() ?? [];เป็นไปได้ว่าคุณต้องการอะไร
อธิการ

0

ฉันไม่คิดว่าจะดีกว่าอีกอันหนึ่งโดยเนื้อแท้ แต่ฉันขอแนะนำให้ใช้ || เนื่องจากเป็นค่าเริ่มต้นในภาษาส่วนใหญ่

แก้ไข: ตามที่คนอื่น ๆ ชี้ให้เห็นว่ามีความแตกต่างระหว่างทั้งสองอย่างแน่นอน


0

ไม่มีอะไรเลวร้ายหรือดีขึ้นเพียงขึ้นอยู่กับลำดับความสำคัญของตัวดำเนินการ เนื่องจาก||มีความสำคัญสูงกว่าorจึงใช้||เป็นส่วนใหญ่


-3

บางภาษาใช้การลัดวงจรและภาษาอื่น ๆ ใช้การประเมินบูลีนเต็มรูปแบบ (ถ้าคุณรู้สิ่งนี้จะคล้ายกับคำสั่ง $Bในภาษาปาสคาล)

คำอธิบาย:

function A(){
    ...Do something..
    return true;
}

function B(){
    ...Do something..
    return true;
}

if ( A() OR B() ) { .....

ในตัวอย่างนี้ฟังก์ชันB()จะไม่ถูกเรียกใช้งาน ตั้งแต่ฟังก์ชั่นA()ส่งคืนค่า TRUE ผลลัพธ์ของคำสั่ง OR จึงเป็นที่รู้จักจากส่วนแรกโดยไม่จำเป็นต้องประเมินส่วนที่สองของนิพจน์

อย่างไรก็ตามด้วย ( A() || B() )ส่วนที่สองจะได้รับการประเมินเสมอโดยไม่คำนึงถึงมูลค่าของส่วนแรก

สำหรับการเขียนโปรแกรมที่ดีที่สุดคุณควรใช้ORสิ่งที่เร็วกว่าเสมอ(ยกเว้นในกรณีที่ส่วนแรกส่งคืนfalseและส่วนที่สองจะต้องได้รับการประเมิน)


นี่ไม่ใช่ 'คำตอบที่ดีที่สุด !!' โปรดเลื่อนกลับขึ้นไปและรับคำตอบที่ได้รับการโหวตมากที่สุดสำหรับคำอธิบายที่ดี ด้วย||, Bจะไม่ถูกเรียก ตัวดำเนินการทั้งสองทำเหมือนกันทุกประการยกเว้นว่าลำดับความสำคัญต่างกัน
bzeaman

"คุณควรใช้หรือเร็วกว่าเสมอ" อืมฉันสงสัยว่านี่เป็นความจริงหรือไม่ ... งั้นมาตรวจสอบกันดีกว่าว่า: 3v4l.org/5QSAA/vld#tabs 3v4l.org/PdjJP/vld#tabsจำนวน opcodes คือ เหมือนกัน. ดังนั้นจึงไม่สำคัญว่าประสิทธิภาพจะฉลาด
Jens
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.