if ('constant' == $ variable) vs. if ($ variable == 'constant')


48

เมื่อเร็ว ๆ นี้ฉันได้ทำงานกับ PHP มากและโดยเฉพาะภายในกรอบ WordPress ฉันสังเกตเห็นรหัสจำนวนมากในรูปแบบของ:

if ( 1 == $options['postlink'] )

ที่ฉันคาดว่าจะเห็น:

if ( $options['postlink'] == 1 )

นี่เป็นข้อตกลงที่พบในบางภาษา / กรอบงานหรือไม่? มีเหตุผลใดที่แนวทางก่อนหน้านี้เป็นที่นิยมกว่าในภายหลัง (จากมุมมองการประมวลผลหรือมุมมองการแยกวิเคราะห์หรือแม้แต่มุมมองของมนุษย์?)

หรือมันเป็นเพียงเรื่องของการลิ้มรส? ฉันมักจะคิดว่ามันจะดีกว่าเมื่อทำการทดสอบว่ารายการตัวแปรที่ทดสอบกับค่าคงที่อยู่ทางซ้าย ดูเหมือนว่าแผนที่ดีกว่าวิธีที่เราจะถามคำถามในภาษาธรรมชาติ: "ถ้าเค้กช็อคโกแลต" มากกว่า "ถ้าช็อคโกแลตเป็นเค้ก"


1
ฉันไม่เคยเขียนโค้ดแบบนี้ แต่จะยุติธรรม "ถ้าช็อคโกแลตเป็นรสชาติของเค้ก" ฟังดูเป็นธรรมชาติ ภาษาธรรมชาติมีความยืดหยุ่นมากขึ้น
Rick Sladkey

4
@Rick มันอาจฟังดูเป็นภาษาธรรมชาติ แต่คุณไม่สามารถปฏิเสธได้ว่าเมื่อคุณเห็นโค้ดเช่นนั้นคุณต้องหยุดก่อน (อาจจะแค่เพียงเสี้ยววินาที) เพื่อคิดว่ามันพยายามทำอะไร
Edgar Gonzalez

4
@Edgar Gonzalez: ตกลงฉันอย่างแน่นหนากับมันในรหัส
Rick Sladkey

3
บทที่ 19 ของCode Complete 2nd Edition (ภายใต้หัวข้อ "นิพจน์บูลีน: ปัญหาทั่วไปกับนิพจน์บูลีน") แนะนำการฝึกนี้ด้วยเหตุผลที่แน่นอนที่ระบุไว้ในคำตอบมากมายที่นี่: เพื่อป้องกันการมอบหมายในภาษา C .
CraigTP

4
ฉันมักจะเห็นสิ่งเหล่านี้เรียกว่า "เงื่อนไขโยดา"
Brian

คำตอบ:


83

เหตุผลหลักในการทำเช่นนี้ (เรียกว่า "เงื่อนไขโยดา") คือการป้องกันอุบัติเหตุโดยที่คุณบังเอิญใช้โอเปอเรเตอร์ที่ได้รับมอบหมาย ( =) แทนโอเปอเรเตอร์การเปรียบเทียบที่เท่ากัน ( ==)

นั่นคือถ้าคุณทำผิดพลาดในการทำ:

$foo = 5;
if ($foo = 1) {
  // Stuff
}

คำสั่งจะประเมินเป็นtrue(หรือในบางภาษาเช่น PHP - ค่าจริง) และคุณจะพบข้อผิดพลาดที่หายาก

แต่ถ้าคุณทำ:

$foo = 5;
if (1 = $foo) {
  // Stuff
}

คุณจะได้รับข้อผิดพลาดร้ายแรงเนื่องจากคุณไม่สามารถกำหนด$fooให้เป็นจำนวนเต็มได้

แต่ในขณะที่คุณชี้ให้เห็นการกลับคำสั่งโดยทั่วไปจะทำให้สิ่งที่อ่านง่ายขึ้น ดังนั้นหลายมาตรฐานการเข้ารหัส ( แต่ไม่ใช่ทั้งหมดรวมทั้ง WordPress ) แนะนำหรือต้องแม้จะมีประโยชน์การล่าสัตว์ของข้อผิดพลาด$foo == 11 == $foo

โดยทั่วไปคำแนะนำของฉันคือการปฏิบัติตามมาตรฐานการเข้ารหัสที่กำหนดไว้ถ้ามีอย่างใดอย่างหนึ่ง: สำหรับ WordPress นั่นหมายถึงการใช้เงื่อนไข Yoda

เมื่อไม่มีและเป็นไปไม่ได้ที่จะสร้างสิ่งนี้ผ่านฉันทามติกับเพื่อนของคุณมันเป็นทางเลือกของดีลเลอร์


2
ฉันจำได้ว่าเมื่อออกแบบภาษา (เมื่อนานมาแล้ว) ที่เราสร้างขึ้น:=เป็นผู้ดำเนินการที่ได้รับมอบหมาย ( ==สำหรับการทดสอบความเท่าเทียมกัน) โดยเฉพาะเพื่อหลีกเลี่ยงปัญหาประเภทนี้
Donal Fellows

7
ฉันได้เขียนหลายหลายบรรทัดของรหัสและฉันไม่เคยพิมพ์ตั้งใจแทน= ==ความแตกต่างนั้นเน้นไปทุกที่ที่ฉันไม่เคยสับสน ในทางกลับกันฉันได้อ่านโค้ดหลาย ๆ ชิ้นที่สับสนหรือยากที่จะเข้าใจ เช่นนี้ฉันจะให้ความสำคัญกับความสามารถในการอ่าน :) โดยไม่คำนึงถึงคำตอบที่ดี
crazy2be

5
อีกเหตุผลที่ดีในการใช้งาน-Wall -Werrorหรือเทียบเท่าของคอมไพเลอร์ / ล่ามของคุณ มีสถานการณ์น้อยมากที่การมอบหมายภายในเงื่อนไขถูกต้องให้อ่านได้มากกว่า หลายภาษาไม่อนุญาตให้ใช้
Karl Bielefeldt

7
Pedantic: ในขณะที่if($foo = 1)ประเมินtrueในบางภาษาใน PHP จะประเมินถึง 1 แทน if($foo = 20)ประเมินถึง 20; if($foo = 0)หาค่าเป็น 0 ซึ่งไม่เหมือนกับค่าอื่น ๆ ที่เป็นเท็จ สิ่งนี้สามารถเพิ่มความซับซ้อนของเลเยอร์ทั้งหมดของข้อผิดพลาด
ชาร์ลส์

2
ที่จริงแล้วมาตรฐานการเข้ารหัสของ WordPress เรียกร้องให้ Yoda Conditionals: codex.wordpress.org/WordPress_Coding_Standards#Yoda_Conditions
Tom Auger

13

มันเป็นกลไกการเข้ารหัสป้องกันเพื่อป้องกันการใช้งานโดยไม่ตั้งใจของผู้ดำเนินการที่ได้รับมอบหมาย

พิจารณาการใช้งานในทางที่ผิด / ข้อผิดพลาดของผู้ดำเนินการที่ได้รับมอบหมายแทนตัวดำเนินการที่เท่าเทียมกัน

if ( $options['postlink'] = 1  )

เงื่อนไขข้างต้นจะกลับมาจริงเสมอ แต่นั่นอาจไม่ใช่สิ่งที่โปรแกรมเมอร์ดั้งเดิมมีอยู่ในใจ ลองพิจารณาดูในที่นี้

if( 1 = $options['postlink'])

นี่, PHP (และภาษาอื่น ๆ ส่วนใหญ่) จะปฏิเสธที่จะทำงานตามที่มันเป็นไปไม่ได้ที่จะกำหนดอะไร1กับค่าคงที่ของ ด้วยการเขียนคำสั่งเงื่อนไขทั้งหมดด้วยวิธีนี้คุณจะมั่นใจได้ว่าไม่มีการใช้งานโดยไม่ตั้งใจของผู้ดำเนินการที่ได้รับมอบหมายในเงื่อนไข


9

ฉันชอบใช้การประชุมนั้นใน java เพื่อลบความเป็นไปได้ของข้อยกเว้นตัวชี้โมฆะ ดังนั้นสิ่งนี้จะไม่ทำให้คุณมีปัญหาหรือต้องการรหัสเพิ่มเติม:

String foo = null;

if ("bar".equals(foo))
{
    //Do something
}

3
ฉันชอบสิ่งนี้ แต่ฉันไม่ชอบความคิดทั่วไป
Thomas Eding

3
หากค่า Null ไม่ถูกต้องในจุดนั้นคุณควรตรวจสอบแล้วหรือสร้างรหัสของคุณในลักษณะที่ค่า Null จะเป็นไปไม่ได้
Ed S.

6
ดูเหมือนจะเป็นวิธีที่ง่ายในการแก้ไขปัญหา ฝุ่นไม่ได้ถูกทำความสะอาดโดยยักเข้าไปในพรม
Lie Ryan

0

ในทางปฏิบัติคอมไพเลอร์หลายคนจะให้คำเตือนถ้าคุณเขียน "if (x = 1)" แทนที่จะเป็น "if (x == 1)" เพราะมันเป็นความผิดพลาด

ด้วยเสียงดังกราวคุณสามารถหลีกเลี่ยงการเตือนด้วยการบอกคอมไพเลอร์ได้อย่างมีประสิทธิภาพ "ฉันหมายถึงมันและฉันรู้ว่าฉันกำลังทำอะไร" และสิ่งนี้ทำได้โดยการเขียน "if ((x = 1))" หมายเหตุวงเล็บพิเศษ ที่ทำงานในสถานการณ์อื่นเช่นกัน ถ้า (เท็จ) คำสั่ง; อาจให้คำเตือนว่าคำสั่งนั้นจะไม่ถูกดำเนินการ คำสั่ง if ((เท็จ)); ไม่ให้คำเตือนนั้น


ฉันชอบมันมาก! ฉันหลีกเลี่ยงสำนวนที่ถูกต้องสมบูรณ์ใน PHP เพราะฉันมักจะได้รับคำเตือนใน IDE ของฉัน:if ($array = getSomething()){ // ..so something with $array }
Tom Auger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.