'AND' vs '&&' เป็นผู้ดำเนินการ


298

ฉันมี codebase ที่นักพัฒนาตัดสินใจที่จะใช้ANDและORแทนและ&&||

ฉันรู้ว่ามีความแตกต่างในความสำคัญของผู้ประกอบการ ( &&ไปก่อนand) แต่ด้วยกรอบงานที่กำหนด ( PrestaShopเพื่อความแม่นยำ) มันชัดเจนว่าไม่มีเหตุผล

คุณใช้เวอร์ชั่นไหน คือandอ่านได้มากขึ้นกว่า&&? หรือไม่มีความแตกต่าง?


1
โปรดทราบว่า~เป็นตัวดำเนินการ NOT ที่ชาญฉลาดไม่ใช่ตรรกะ ;-)
Gumbo

2
ใช่ฉันรู้. นิสัยที่ไม่ดี :) . เป็นเรื่องแปลกเล็กน้อยที่ใน PHP มี 'และ', 'หรือ' และ 'xor' แต่ไม่มี 'ไม่' ใช่ไหม
ts

1
@ts: คำตอบที่ถูกต้องที่นี่คือคำตอบที่ถูกจัดทำโดย R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/ …
Marco Demaio

4
! เป็นตัวดำเนินการที่ไม่ใช่ตรรกะ
Razor Storm

2
@chiliNUT ค่อนข้างถูกต้อง ในเวลานั้นจะต้องทำให้รู้สึก ดูเหมือนว่าคำตอบที่ไม่ถูกต้องที่ซุ่มซ่อนถูกลงโทษ ณ จุดนี้ :)
doublejosh

คำตอบ:


664

หากคุณใช้ANDและORในที่สุดคุณก็จะได้รับสิ่งที่ชอบเช่นนี้:

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

ต้องการเดาว่า$truthinessเท่ากับอะไร?

ถ้าคุณพูดว่าfalse... bzzzt ขอโทษผิด!

$truthinesstrueดังกล่าวข้างต้นมีค่า ทำไม? =มีลำดับความสำคัญสูงandกว่า การเพิ่มวงเล็บเพื่อแสดงลำดับโดยนัยทำให้ชัดเจนยิ่งขึ้น:

($truthiness = $this_one) and $that

หากคุณใช้&&แทนในตัวอย่างรหัสแรกก็จะทำงานตามที่คาดไว้และandfalse

ตามที่กล่าวไว้ในความคิดเห็นด้านล่างนี้ยังทำงานเพื่อรับค่าที่ถูกต้องเนื่องจากวงเล็บมีลำดับความสำคัญสูงกว่า=:

$truthiness = ($this_one and $that)

135
+1: สิ่งนี้ควรมีความชัดเจนในเอกสาร PHP หรือ PHP ควรเปลี่ยนและให้ความสำคัญกับตัวดำเนินการเหล่านี้หรือ DEPRECATE and orทุกครั้ง ฉันเห็นคนจำนวนมากเกินไปคิดว่าพวกเขาเป็นสิ่งเดียวกันและคำตอบที่นี่เป็นคำรับรองเพิ่มเติม
Marco Demaio

11
ที่จริงแล้วภาษาอื่น ๆ (เช่น Perl และ Ruby) ก็มีตัวแปรเหล่านี้ที่มีความแตกต่างที่มีความสำคัญเหมือนกันดังนั้นจึงไม่มีเหตุผลที่จะเบี่ยงเบนจากมาตรฐานนี้ ไม่ต้องพูดถึงความเข้ากันได้ย้อนหลังของแอพพลิเคชัน PHP มากมาย
Mladen Jablanović

23
การที่คนไม่สามารถอ่านเอกสารสำหรับภาษานั้นไม่ได้ทำให้การตัดสินใจของภาษาผิดไป ในฐานะที่เป็น Mladen บันทึก Perl และ Ruby ยังใช้ตัวดำเนินการพิเศษเหล่านี้และมีความสำคัญเหมือนกัน จะช่วยให้การสร้างเช่น$foo and bar()ซึ่งเป็นทางลัดที่ดีสำหรับถ้างบ หากพฤติกรรมที่ไม่คาดคิด (จากเอกสารที่ไม่ดีหรือไม่อ่าน) มีเหตุผลที่จะไม่ใช้สิ่งที่เราจะไม่พูดถึงเกี่ยวกับการใช้ PHP เลย
Altreus

2
ผมใช้เวลา 3 นาทีเพื่อหาสายที่ไม่ถูกต้อง: $ นี้ = true , :( และสิ่งที่เกี่ยวกับ $ truthiness = ($ และ $ ที่); มันดูดีกว่าสำหรับผม :)
Dmitriy Kozmenko

6
ฉันเห็นด้วยกับ Dmitriy - การห่อการประเมินผลแบบบูลในวงเล็บช่วยอธิบายความตั้งใจของรหัส ฉันคิดว่าโอเปอเรเตอร์และฟังก์ชั่นที่ใช้งานอยู่ตอนนี้มีคุณค่าและสอดคล้องกับภาษาอื่น ๆ มันเป็นหน้าที่ของโปรแกรมเมอร์ที่จะเข้าใจภาษา
Jon z

43

ขึ้นอยู่กับวิธีการใช้งานมันอาจจำเป็นและมีประโยชน์ 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 ได้กล่าวถึง


2
เป็นที่น่าสังเกตว่า "ความจริง" จะไม่ถูกเพิกเฉยถ้านิพจน์นั้นเป็นส่วนหนึ่งของคำสั่งขนาดใหญ่ พิจารณากรณีif ($f = false or true) $f = true;- ผลลัพธ์จะ$fเป็นจริงในท้ายที่สุดเนื่องจากนิพจน์ประเมินว่าเป็นความจริงโดยรวม
Chris Browne

1
ไม่คุณเพียงแค่เขียนทับตัวแปรในภายหลัง นิพจน์ยังคงประเมินว่าเป็นเท็จจากนั้นคุณเขียนทับด้วยความจริงในบรรทัดถัดไป
r3wt

2
จริงๆแล้วเขาพูดถูก ก่อน$fได้รับมอบหมายเท็จ - แต่เงื่อนไขประเมินว่าเป็นจริงดังนั้นจึง$fถูกเขียนทับ หากเงื่อนไขประเมินเป็นเท็จ$fจะไม่ถูกเขียนทับด้วยวิธีใด
ahouse101

มันไร้สาระที่จะแนะนำนักพัฒนาควรทำตามรสนิยมของตนเอง ลืมฝันร้ายของนักพัฒนาอื่นพยายามที่จะรักษารหัสเดียวกันนักพัฒนาที่เขียนรหัสของตัวเองจะทำผิดพลาดความหมายในรหัสที่เป็นลายลักษณ์อักษรเพราะ s / เขาที่แนะนำandในช่วง&&ที่andผลงานตามที่คาดไว้เพียงบางสถานการณ์และ&&ผลงานตามที่คาดไว้ในทุก สถานการณ์
ADTC

13

เพื่อความปลอดภัยฉันมักจะใส่วงเล็บเปรียบเทียบและเว้นวรรคไว้เสมอ ด้วยวิธีนี้ฉันไม่จำเป็นต้องพึ่งพาตัวดำเนินการที่มีความสำคัญ:

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

29
โดยส่วนตัวแล้วฉันคิดว่าการเพิ่มวงเล็บที่ไม่จำเป็นเพิ่มเติมทำให้สับสนในการอ่านมากกว่าการมีสิ่งที่คุณต้องการ ตัวอย่างเช่นฉันคิดว่านี่อ่านง่ายกว่ามาก: if (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
rooby

4
ฉันคิดว่านี่เป็นโค้ดที่สวยที่สุดที่ฉันเคยดูมาทั้งวัน ทำได้ดีมาก
rm-vanda

เนื่องจาก PHP เป็นภาษาที่ถูกตีความมันจะทำงานได้อย่างรวดเร็วหากคุณไม่ใช้ช่องว่างที่ไม่จำเป็นหรือบรรทัดใหม่ในรหัสของคุณ หากคุณทำเช่นเดียวกันกับภาษาที่คอมไพล์แล้วจะใช้เวลาในการรวบรวมเท่านั้น แต่จะไม่มีผลกับรันไทม์ ฉันไม่ได้หมายถึงการทำมันครั้งเดียวจะทำเครื่องหมายความแตกต่าง แต่ในแอปพลิเคชันทั้งหมดที่ใช้ php + javascript ทั้งสองเขียนเหมือนตัวอย่าง ... เวลาโหลดจะยิ่งใหญ่ขึ้นอย่างแน่นอน คำอธิบาย: ช่องว่างและบรรทัดใหม่จะถูกละเว้น แต่หากต้องการเพิกเฉยจะต้องทำการตรวจสอบ สิ่งนี้เกิดขึ้นที่รันไทม์บน lang ที่ถูกตีความและเมื่อรวบรวมบนคอมไพล์แล้ว
JoelBonetR

@JoelBonetR หากคุณใช้ php opcache หรือคล้ายกันกับความกังวลของคุณเกี่ยวกับเวลาในการโหลดนั้นไม่เกี่ยวข้อง ฉันหวังว่าไม่มีใครที่ทำงานสถานที่ผลิต PHP โดยไม่ได้ ...
PeloNZ

@PeloNZ เพื่อให้คุณสามารถเขียนสกปรกเพราะมันจะถูกเก็บไว้ต่อไปและโครงการทั้งหมดจะใช้เวลาเพียงไม่กี่วินาทีในการโหลดเมื่อรีเฟรชใช่มั้ย? การทำความสะอาดโค้ดสำหรับตัวคุณเองและเพื่อนร่วมทีมของคุณเกี่ยวกับการกำหนดเวลาเป็นเพียงจุดที่ผู้คนส่วนใหญ่ไม่สนใจหรือไม่รู้เลย
JoelBonetR

11

ลำดับความสำคัญที่แตกต่างกันระหว่าง&&และและ (&& มีความสำคัญสูงกว่าและ) สิ่งที่ทำให้เกิดความสับสนเมื่อรวมกับผู้ประกอบการที่สาม ตัวอย่างเช่น

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

จะคืนค่าสตริงในขณะที่

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

จะกลับบูล


10

เนื่องจาก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

2

ให้ฉันอธิบายความแตกต่างระหว่าง“ และ” -“ &&” -“ &”

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

ลำดับความสำคัญ (ลำดับความสำคัญ) ของโอเปอเรเตอร์ระบุว่า "แน่น" มันผูกสองนิพจน์เข้าด้วยกัน ตัวอย่างเช่นในนิพจน์ 1 + 5 * 3 คำตอบคือ 16 และไม่ใช่ 18 เนื่องจากตัวดำเนินการคูณ ("*") มีลำดับความสำคัญสูงกว่าตัวดำเนินการบวก ("+")

การผสมพวกมันเข้าด้วยกันในการดำเนินการครั้งเดียวอาจให้ผลลัพธ์ที่ไม่คาดคิดในบางกรณีที่ ฉันแนะนำให้ใช้ && ตลอดเวลา แต่นั่นคือตัวเลือกของคุณ


ในทางตรงกันข้าม "&" เป็นค่าที่เหมาะสมและการดำเนินงาน มันใช้สำหรับการประเมินและการจัดการบิตเฉพาะภายในค่าจำนวนเต็ม

ตัวอย่างถ้าคุณทำ (14 & 7) ผลลัพธ์จะเป็น 6

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

1

คุณใช้เวอร์ชั่นไหน

หากมาตรฐานการเข้ารหัสสำหรับ codebase เฉพาะที่ฉันกำลังเขียนรหัสเพื่อระบุโอเปอเรเตอร์ที่ควรใช้ฉันจะใช้มันอย่างแน่นอน หากไม่ได้และรหัสกำหนดว่าควรใช้ (ไม่บ่อยสามารถแก้ไขได้ง่าย) จากนั้นฉันจะใช้ มิฉะนั้นอาจจะ &&

'และ' อ่านง่ายกว่า '&&' มากกว่าหรือไม่

มันคือการอ่านได้มากขึ้นกับคุณ คำตอบคือใช่และไม่ขึ้นอยู่กับปัจจัยหลายอย่างรวมถึงรหัสรอบผู้ปฏิบัติงานและแน่นอนคนที่อ่านมัน!

|| มีความแตกต่าง ~ เหรอ?

ใช่. ดูผู้ประกอบการตรรกะสำหรับการ||และผู้ประกอบการระดับบิต~สำหรับ


0

ฉันคิดว่ามันเป็นเรื่องของรสนิยมแม้ว่า (ตั้งใจ) ผสมเข้าด้วยกันอาจทำให้เกิดพฤติกรรมที่ไม่พึงประสงค์:

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

true and false || false; // returns true

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

UPDATE : เกี่ยวกับความคิดเห็นที่บอกว่าการดำเนินการทั้งสองคืนเท็จ ... จริง ๆ แล้วโค้ดข้างต้นไม่ได้คืนสิ่งใดฉันขอโทษสำหรับความคลุมเครือ เพื่อชี้แจง: พฤติกรรมในกรณีที่สองขึ้นอยู่กับวิธีการใช้ผลลัพธ์ของการดำเนินการ สังเกตว่าการมาก่อนของตัวดำเนินการมาที่นี่:

var_dump(true and false || false); // bool(false)

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

เหตุผลที่$a === trueเป็นเพราะผู้ประกอบการที่ได้รับมอบหมายมีความสำคัญมากกว่าผู้ประกอบการทางตรรกะใด ๆ ตามที่อธิบายไว้แล้วอย่างดีในคำตอบอื่น ๆ


16
สิ่งนี้ไม่เป็นความจริงพวกเขาทั้งหมดกลับเท็จ
Jay

0

นี่คือตัวอย่างตัวนับเล็กน้อย:

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

เอาท์พุท:

bool(false)

ฉันจะบอกว่าการพิมพ์ผิดประเภทนี้มีแนวโน้มที่จะก่อให้เกิดปัญหาที่ร้ายกาจ (ในแบบเดียวกับ=vs ==) และมีโอกาสน้อยที่จะสังเกตได้มากกว่าadn/ rotypos ซึ่งจะตั้งค่าสถานะเป็นข้อผิดพลาดทางไวยากรณ์ ฉันค้นหาและ / หรืออ่านง่ายขึ้นมาก FWIW, เฟรมเวิร์ก PHP ส่วนใหญ่ที่แสดงการตั้งค่า (ส่วนใหญ่ไม่ได้) ระบุและ / หรือ ฉันยังไม่เคยเจอกรณีที่แท้จริงและไม่มีการวางแผนที่จะมีความสำคัญ


0

ตัวอย่างที่ดีอีกข้อหนึ่งที่ใช้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, false true, true, falseดูhttps://ideone.com/lsqovsสำหรับตัวอย่างที่ซับซ้อน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.