ไม่“ ถ้า (0 == ค่า) …” ทำอันตรายมากกว่าดีไหม? [ปิด]


49

นี่เป็นหนึ่งในสิ่งที่ฉันเกลียดที่สุดเมื่อฉันเห็นมันในรหัสของคนอื่น ฉันรู้ว่ามันหมายถึงอะไรและทำไมบางคนทำเช่นนี้ ("จะเกิดอะไรขึ้นถ้าฉันใส่ '=' แทนโดยบังเอิญ?") สำหรับฉันมันเหมือนเป็นอย่างมากเมื่อเด็กคนหนึ่งเดินลงบันไดเพื่อนับก้าวออกมาดัง ๆ

อย่างไรก็ตามนี่คือข้อโต้แย้งของฉันกับมัน:

  • มันขัดขวางการไหลตามธรรมชาติของการอ่านรหัสโปรแกรม เรามนุษย์พูดว่า "ถ้าค่าเป็นศูนย์" และไม่ใช่ "ถ้าเป็นศูนย์คือค่า"
  • คอมไพเลอร์สมัยใหม่เตือนคุณเมื่อคุณมีงานที่มอบหมายในสภาพของคุณหรือที่จริงแล้วถ้าเงื่อนไขของคุณประกอบด้วยเพียงการมอบหมายนั้นซึ่งใช่ดูน่าสงสัยอยู่แล้ว
  • คุณไม่ควรลืมใส่ double '=' เมื่อคุณเปรียบเทียบค่าหากคุณเป็นโปรแกรมเมอร์ คุณอาจลืมใส่ "!" เช่นกัน เมื่อทดสอบความไม่เท่าเทียมกัน

17
ฉันไม่สนใจมันมากนัก แต่มันค่อนข้างไกลลิสต์สัตว์เลี้ยงส่วนตัวของฉัน
Adam Crossland

7
และโปรแกรมเมอร์ก็คิดถึงคู่ '=' บางครั้ง มันเป็นความผิดพลาดง่าย ๆ ในการทำและเป็นสิ่งที่มองข้ามได้ง่าย
ประหลาดใจ

8
สิ่งนี้ไม่สร้างสรรค์หรือไม่เป็นคำถามจริง
TheLQ

7
นี่เป็นความเห็นสั้น ๆ ของฉัน: ผู้คนสามารถจำเขียน0 == valueได้ แต่อย่าลืมเขียน==? ฉันหมายถึง blimey หากคุณกำลังคิดเกี่ยวกับมันทำไมไม่เขียนมันอย่างถูกต้องเพื่อเริ่มต้นด้วย
ดร. Hannibal Lecter

3
@muntoo: ตามคอมไพเลอร์มีหลายสิ่งที่ "ถูกต้อง" ฉันไม่คิดว่ามันเป็นมาตรฐานที่ดีมาก
ดร. Hannibal Lecter

คำตอบ:


59

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

อย่างที่คนอื่น ๆ พูดกันแน่นอนว่ามันไม่ใช่ปัญหา แต่มันก่อให้เกิดความไม่ลงรอยกันทางปัญญาเล็กน้อย


32
+1 สำหรับ "เงื่อนไขโยดา" จริง ๆ แล้วฉันต้องการที่ :)
Bobby Tables

3
ในขณะที่การสั่งซื้อไม่เป็นไรฉันคัดค้านการเปรียบเทียบกับศูนย์แทนที่จะเป็นแบบบูลธรรมดา, if(!value).
เอสเอฟ

1
ดังนั้นคุณพิจารณามอบหมายให้ภายในข้อผิดพลาดตามเงื่อนไข?

4
"ภาษาสมัยใหม่ส่วนใหญ่ไม่แม้แต่จะรวบรวมสิ่งนี้"ปัญหาเกิดขึ้นเมื่อคุณใช้ภาษาที่บีบบังคับผลของการมอบหมายให้เป็นบูลีนอย่างเงียบ ๆ ภาษาที่ได้รับความนิยมมากที่สุดที่ฉันนึกได้นั่นก็คือ JavaScript นี่คือเหตุผลที่ฉันมักจะใช้เงื่อนไข yoda แม้ใน Java เพื่อที่ฉันจะไม่ลืมที่จะทำเมื่อฉันเขียนจาวาสคริปต์ ฉันสลับไปมาระหว่างคนทั้งสองบ่อยพอที่จะสามารถ (และมี) เป็นปัญหาได้
Sam Hasler

3
ไม่มีใครรู้ว่าคอมไพเลอร์ที่จะไม่รวบรวมif (0 == x)?
Kristopher Ives

56

มันน่ารังเกียจเพราะเรียกเก็บภาษีจิตขนาดเล็ก แต่เห็นได้ชัด

ผู้คนอ่านจากซ้ายไปขวาในแทบทุกภาษาโปรแกรม (และภาษาที่เป็นธรรมชาติที่สุด)

ถ้าฉันเห็น123 == xวิธีที่ฉันใช้ในการแยกวิเคราะห์จิตใจ:

  • 123- เพื่ออะไร ข้อมูลไม่สมบูรณ์
  • == - ดี 123 คือ 123 ทำไมต้องทดสอบ ...
  • x- ตกลงนั่นคือสิ่งที่เราเป็นห่วง ตอนนี้ฉันมีบริบทเท่านั้น
  • กลับไปที่การพิจารณาอีกครั้ง123และทำไมจึงเปรียบเทียบกับ x

เมื่อฉันเห็นการx == 123แยกวิเคราะห์ทางจิตคือ:

  • x- ให้บริบทฉันรู้ว่าเงื่อนไขเป็นอย่างไร ฉันอาจเลือกที่จะไม่สนใจส่วนที่เหลือ ขึ้นอยู่กับขั้นตอนก่อนหน้านี้ฉันมีความคิดที่ดีว่าเพราะอะไรและจะเกิดอะไรขึ้น (และต้องแปลกใจถ้ามันแตกต่างกัน)
  • == - ฉันคิดอย่างนั้น
  • 123 - ได้.

การหยุดชะงักมีขนาดเล็ก (ในตัวอย่างง่ายๆ) แต่ฉันมักจะสังเกตเห็นมัน

ใส่ค่าแรกอาจเป็นความคิดที่ดีถ้าคุณต้องการที่if (LAUNCH_NUKES == cmd)จะดึงความสนใจกับมันเช่น ปกติแล้วนี่ไม่ใช่ความตั้งใจ


5
เผง ในภาษาธรรมชาติอย่างต่อเนื่องเสมอมาสุดท้ายด้วยเหตุผลเดียวกันถ้าแสงเป็นสีแดง ...
mojuba

2
@mojuba จริงมันเป็นสากลเกือบ มีภาษาธรรมชาติอยู่สองสามภาษาที่วัตถุมาก่อนหัวเรื่อง (คำสั่ง OVS / OSV) แต่พวกมันไม่ชัดเจน
dbkk

1
ในทางกลับกันเราบางคนมักจะอ่านสัญลักษณ์ก่อนตัวแปร พวกเขาสะดุดตามากขึ้น ดังนั้นผมจึงจะแยกออก=หรือ==ก่อน123หรือxและท้ายไม่ได้รบกวนการแปลรหัสเป็นภาษาอังกฤษในหัวของฉัน
Izkata

นอกจากนี้คอมไพเลอร์ส่วนใหญ่จะเตือนหากได้รับแจ้งอย่างถูกต้องเว้นแต่จะใช้การจัดฟันแบบพิเศษดังนั้นจึงพยายามแก้ไขปัญหาที่ไม่เป็นปัญหา
Deduplicator

47

อันตรายหรือไม่ ไม่มันทำงานได้ทั้งสองทาง

การปฏิบัติที่ไม่ดี? เป็นที่ถกเถียงกันมากที่สุด มันเป็นโปรแกรมป้องกันอย่างง่าย

คุ้มค่าที่จะนอนไม่หลับใช่มั้ย Nah


8
และเมื่อฉันอ่านฉันเข้าใจรหัสทันทีซึ่งเป็นเหตุผลที่สำคัญที่สุดสำหรับฉันในการอภิปรายเกี่ยวกับรูปแบบการเข้ารหัส ฉันเห็นด้วยทั้งหมดไม่คุ้มค่าที่จะนอนไม่หลับ
Jeff Siver

17

นี่คือ flaimbait โดยทั่วไป

ไม่มันไม่ได้ทำอันตรายมากกว่าความดี ง่าย

คำอื่น ๆ

อาร์กิวเมนต์คอมไพเลอร์? เอ่อบางทีอาจจะ - อย่าใส่ความเชื่อมั่นมากเกินไปในการเขียนเพื่อช่วยคุณจากตัวคุณเอง

"คุณไม่ควรลืม" - ดีduh - ไม่มีของหลักสูตรที่คุณไม่ควรขณะที่ฉันเหนื่อยฉันได้รับการเข้ารหัสทุกวันที่ฉันได้มีการใช้สองภาษาที่แตกต่างกันและบางครั้งเพียงแค่บางครั้งการเป็นมนุษย์ที่ฉันทำ ความผิดพลาด.

ประเด็นของพฤติกรรมแบบนี้ก็คือการป้องกันมันไม่ได้อยู่ที่นั่นเพราะคุณคาดว่าจะทำผิดพลาดมากกว่าที่คุณมีประกันเพราะคุณคาดหวังว่าจะผิดพลาด ... แต่ถ้าคุณทำดีที่ได้รับความคุ้มครอง

อ่านยาก คุณกำลังบ่นว่าโปรแกรมเมอร์ที่ดีควรมี == เดินสาย (ซึ่งทำให้ทุกชนิดของสมมติฐานที่ไม่ดี) แต่ที่โปรแกรมเมอร์ที่ดีเหมือนกันตัวเองไม่สามารถอ่าน 0 == ค่า ??

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


6
ฉันคิดว่าค่า 0 == อ่านผิดธรรมชาติสำหรับผู้ที่ศึกษาวิธีพีชคณิตก่อนที่จะศึกษาการเขียนโปรแกรม
mojuba

4
นั่นไม่ใช่ประเด็น - ใช่คุณพูดถูกมันอ่านไม่ออก แต่พอ ๆ กันกับสิ่งที่เราในฐานะโปรแกรมเมอร์เขียนไม่ได้ซ้อนกันเป็นภาษาธรรมชาติและเป็นวิธีที่คุณตีความสิ่งที่ คุณเห็น
Murph

4
ไชโย .. ไม่ต้องพูดถึงความจริงที่ว่าเพราะมันอ่านผิดธรรมชาติคุณมีแนวโน้มที่จะให้ความสนใจกับมันมากขึ้น
mocj

7
@mocj - ดังนั้นเราทุกคนควรเขียนโค้ดให้มากที่สุดเพื่อให้แน่ใจว่าผู้ที่อ่านรหัสของเราจำเป็นต้องอ่านรหัสของเราจริงๆ ?
Kaz Dragon

6
@mocj - ฉันขอขอบคุณที่ แต่ข้อโต้แย้งของคุณคือ "สมองพูดติดอ่าง" ในขณะที่คุณกำลังอ่านเงื่อนไขโยดาเป็นสิ่งที่ดี ฉันถามคำถามว่าถ้าเป็นเช่นนั้นเราควรตั้งเป้าที่จะเขียนโค้ดทั้งหมดเพื่อที่จะทำให้เกิด "สมองติดขัด" หรือไม่? คำถามของแท้
Kaz Dragon

11

ฉันจะไม่เรียกมันว่าเป็นอันตราย แต่มันน่ารังเกียจ ดังนั้นฉันจะไม่บอกว่าจะทำ


10

ฉันไม่เคยรู้สึกเลยว่า 'จะเกิดอะไรขึ้นถ้าฉันลืม a =' เคยมีน้ำหนักมากจริงๆ ใช่คุณอาจพิมพ์ผิด แต่เราทุกคนทำผิดพลาดดูเหมือนว่าโง่ที่จะเปลี่ยนรูปแบบการเข้ารหัสทั้งหมดของคุณเพราะคุณกลัวที่จะทำผิดพลาด ทำไมไม่ทำให้ตัวแปรและฟังก์ชั่นทั้งหมดของคุณเป็นตัวพิมพ์เล็กทั้งหมดโดยไม่มีการลงโทษเพราะคุณอาจลืมที่จะใช้ประโยชน์บางอย่างหรือลืมขีดล่างหนึ่งวัน


5
นั่นไม่ใช่ประเด็นของคำถามประเด็นคือ "มันอันตราย" - และไม่ใช่ อาการระคายเคืองเล็กน้อยที่เลวร้ายที่สุด แต่ไม่เป็นอันตราย
Murph

1
ในภาษาแบบไดนามิก - แน่นอนคุณอาจพิมพ์ผิดสัญลักษณ์และเสียเวลาในภายหลังเพื่อค้นหาแหล่งที่มาของข้อผิดพลาดของคุณ
mojuba

3
ด้วยความเคารพเมื่อคุณใช้เวลาช่วงดึก (หรือสอง) และค้นหาแหล่งที่มา (ในรหัส C ++) คือ = แทนที่จะ == มันจะมีน้ำหนัก
DevSolo

2
@DevSolo: ฉันคิดว่าควรจะเกิดขึ้นจริง ๆ ครั้งหรือสองครั้งในอาชีพของคุณ แต่ไม่มากไปกว่านั้น
mojuba

9

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

วิธีที่ 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

วิธีที่ 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

บางคนรู้สึกว่าตัวอย่างที่สองนั้นมีความกระชับมากกว่าหรือมีข้อโต้แย้งย้อนกลับแสดงให้เห็นถึงจุดของการทดสอบ (มีเงื่อนไข) ก่อนการทดสอบ

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

ผสมให้เข้ากับประเด็นที่ดูเหมือนว่ามีคนแตกต่างกันถึงหกคนที่มีสไตล์ที่เป็นเอกลักษณ์ของตัวเองที่ทำงานในครั้งเดียวฉันรู้สึกรำคาญเล็กน้อย


4
ตัวอย่างที่สองทำให้ฉันไป "ฮะ?" แรกคืออ่านได้มากขึ้น ตัวอย่างที่ดี :)
Mateen Ulhaq

6

สำหรับฉันมันเป็นเงื่อนไขที่เรียบง่าย ในฐานะคนที่เรียนรู้ C (ในยุค 90) C และ C ++ ฉันเริ่มคุ้นเคยกับมันมากขึ้นและยังคงใช้มันแม้ว่าเหตุผลจะลดน้อยลง

เมื่อคุณ "ปรับ" เพื่อดูด้านซ้ายสำหรับ "คงที่" มันจะกลายเป็นธรรมชาติที่สอง

ฉันยังใช้เพื่อความเท่าเทียมเท่านั้น

ฉันเห็นด้วยกับคำตอบของ @ Wonko


5

กรณีหนึ่งที่ฉันพบว่ามีประโยชน์คือส่วนที่ตัวแปรของ if นั้นค่อนข้างยาวและการเห็นค่าต่างๆทำให้โค้ดอ่านง่ายขึ้น ภาษาเนมสเปซประมีตัวอย่างที่ดีที่สุด

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

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

เป็นที่ยอมรับในตัวอย่างนี้มีวิธีอื่นในการทำเช่นนี้ แต่ในกรณีนี้อาจเป็นรุ่นที่อ่านได้ครั้งแรก


2
ผมคิดว่าคำหลักที่นี่คือ "วิธีการอื่น ๆ การทำเช่นนี้";)
mojuba

ในกรณีนี้ใช่ แต่ในบางกรณีนี่ก็ยังเป็นผลลัพธ์ที่อ่านง่ายที่สุด จุดเดียวของฉันคือมีเหตุผลบางประการที่ถูกต้องตามกฎหมายสำหรับการทำสิ่งนี้นอกเหนือจากการต่อสู้กับภาษาหรือพฤติกรรม IDE และประเภท -O
บิล

พูดตามตรงฉันมีปัญหากับเงื่อนไขโยดาสำหรับ <= และ> = เครื่องหมาย == เป็นเรื่องที่แตกต่างกันเพราะในหัวของฉันฉันสามารถสลับสัญลักษณ์ไปรอบ ๆ ได้ แต่ในกรณีของคุณฉันต้องจำจำนวนนั้น () ต้องมากกว่าหรือเท่ากับ 2 และนั่นค่อนข้างน่ารำคาญที่จะสืบหาจาก เครื่องหมายที่เล็กกว่าหรือเท่ากับ
อเล็กซ์

3

และยังมีข้อผิดพลาดเกิดขึ้น และบางครั้งคุณต้องการการมอบหมายในโอเปอเรเตอร์ลูปที่คุณอาจตรวจสอบความเท่าเทียมกันหรืออย่างน้อยก็เป็นแบบฝึกหัดมาตรฐานที่จะใช้

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

ดังนั้นฉันจะพูดว่า:

if ( 0 <= value )

แต่ฉันก็จะพูดว่า:

if ( value <= 100 )

ความเท่าเทียมกันฉันมักจะตรวจสอบกับตัวแปรทางซ้ายแม้ว่ามันจะอ่านง่ายขึ้น


1
ฉันเคยใช้if(y > x)ตลอดเวลา เว้นแต่yจะเป็นค่าคงที่
Mateen Ulhaq

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