แบ่งในกรณีเริ่มต้นในสวิตช์


88

ฉันเป็นบิตงงงวยในเมื่อใดก็ตามหรือไม่รวมถึงหลังจากกรณีที่ผ่านมามักจะbreakdefault

switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

        break; // Is it considered to be needed?
}

breakมีวัตถุประสงค์เพียงอย่างเดียวในความเข้าใจของฉันที่จะหยุดรหัสจากการทำงานผ่านส่วนที่เหลือของswitch-case

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

ซึ่งอาจจะได้ในระดับหนึ่งนำมาเปรียบเทียบกับตอนจบไฟล์ที่มี.php ?>ฉันไม่เคยลงท้ายด้วย?>ส่วนใหญ่เนื่องจากความเสี่ยงของการแสดงผลช่องว่าง แต่ก็สามารถยืนยันได้ว่ามันจะเป็นสิ่งตรรกะที่จะจบไฟล์ด้วย

คำตอบ:


144

breakไม่จำเป็นต้องใช้ทางเทคนิคหลังจากทางเลือกสุดท้าย (ซึ่งคุณไม่จำเป็นต้องdefault: มันถูกกฎหมายอย่างสมบูรณ์แบบและบางครั้งก็มีประโยชน์ที่จะทำให้defaultสาขาแรก); ไม่ว่ารหัสของคุณจะอยู่ท้ายswitchคำสั่งหรือbreaksท้ายที่สุดของสาขาสุดท้ายจะมีผลลัพธ์เหมือนกัน

อย่างไรก็ตามฉันยังคงปิดทุกสาขารวมถึงสาขาสุดท้ายด้วยข้อความreturnหรือbreakด้วยเหตุผลสามประการ:

  1. Refactorability หากสาขาทั้งหมดของคุณลงท้ายด้วยbreakหรือreturnคุณสามารถจัดลำดับใหม่ได้โดยไม่ต้องเปลี่ยนความหมาย สิ่งนี้ทำให้มีความเป็นไปได้น้อยที่คำสั่งใหม่จะแนะนำการถดถอย
  2. ความสอดคล้องและความประหลาดใจอย่างน้อยที่สุด ความสอดคล้องกล่าวว่าสาขาของคุณควรจบอย่างสม่ำเสมอเว้นแต่พวกเขาจะแตกต่างกันในความหมาย หลักการของความประหลาดใจอย่างน้อยบอกให้สิ่งที่คล้ายกันควรมีลักษณะคล้ายคลึงกัน การสิ้นสุดสาขาสุดท้ายของswitchบล็อกให้เหมือนกันกับการเติมเต็มก่อนหน้านี้ทำให้การอ่านและความเข้าใจง่ายขึ้น หากคุณไม่ระบุชัดเจนbreakสาขาสุดท้ายจะแตกต่างกันอย่างชัดเจน(ซึ่งเป็นสิ่งสำคัญอย่างยิ่งสำหรับการสแกนอย่างรวดเร็ว) และเพื่อที่จะเห็นว่ามันไม่แตกต่างกันจริงๆผู้อ่านจะต้องลงไปที่ระดับ nitty-gritty .
  3. ปกป้องตัวเอง หากคุณสร้างนิสัยในการปิดswitchสาขาทั้งหมดด้วย a breakมันจะกลายเป็นอัตโนมัติหลังจากผ่านไปครู่หนึ่งและคุณจะมีโอกาสน้อยที่จะลืมโดยไม่ได้ตั้งใจในที่ที่มันสำคัญ ฝึกฝนตัวเองเพื่อคาดหวังว่าbreakในตอนท้ายของทุกสาขาจะช่วยตรวจสอบbreakข้อความที่หายไปซึ่งเหมาะสำหรับการแก้ไขข้อบกพร่องและการแก้ไขปัญหา

ขอบคุณสำหรับความเข้าใจของคุณในเรื่องนี้! จะbreakมีอายุกรณีเช่นกัน :)
โรบิน Castlin

7
ใน C #, break(หรือคำสั่งควบคุมการไหลอื่น ๆ ที่ออกจากcase) มีความจำเป็นทางเทคนิคหลังจากทางเลือกสุดท้าย
dan04

3
@ dan04: ใช่จุดดี C # เป็นข้อยกเว้นที่นี่และอาจเป็นเพราะนักออกแบบภาษารู้เกี่ยวกับปัญหาการswitchล้มในภาษาที่มีอยู่และต้องการป้องกันพวกเขา กฎ C # กำหนดให้ตรงกับคำแนะนำจากคำตอบของฉัน
tdammers

คุณพูดภาษาอะไรกันเป็นพิเศษ? C? c ++? C #? Java? PHP?
svick

2
คอมไพเลอร์ที่ดีจะถือว่าสุดท้ายbreakเป็น NO-OP แทนที่จะสร้างjmpคำสั่งต่อไปถูกต้องหรือไม่
Nathan Osman

11

ได้รับความคลุมเครือที่มีอยู่รอบ ๆ ใช้switch-caseในภาษามากที่สุดเมื่อใช้มันผมจะแนะนำเสมอโดยใช้breakคำสั่งยกเว้นเมื่อมันเป็นอย่างชัดเจนและจากการออกแบบที่ไม่ต้องการ

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


7
เมื่อฉันต้องการให้กรณีหนึ่งผ่านไปยังอีกกรณีหนึ่ง (และไม่ใช่กรณีที่เลวลงcase foo: case bar: ...) ฉันใส่ความคิดเห็นที่ชัดเจนในการที่ฉันต้องการให้เกิดการล้ม ทำให้ชัดเจนมากขึ้น
Donal Fellows

3
ใช่เช่นความคิดเห็นง่าย ๆ// no breakแทนbreak;
Pacerier

หรือ[[fallthrough]]แอตทริบิวต์ในกรณีของ C ++
Ruslan

1

ไม่breakจำเป็นหลังจากกรณีสุดท้าย ฉันใช้คำว่า " last " (ไม่ใช่ค่าเริ่มต้น ) เพราะไม่จำเป็นต้องใช้ตัวพิมพ์เล็กและตัวใหญ่เป็นตัวสุดท้าย

switch(x)
{
case 1:
//do stuff
break;

default:
//do default work
break;

case 3:
//do stuff

}

และเรารู้ว่าbreak เป็นสิ่งที่จำเป็นระหว่างสองติดต่อกันcases บางครั้งฉันใช้if(a!=0)ในโค้ดเพื่อให้อ่านง่ายขึ้นเมื่อผู้อื่นอ้างถึงโค้ดของฉัน ฉันสามารถเลือกที่จะใช้if(a)ซึ่งเป็นเรื่องที่ฉันเลือก


5
สำหรับฉันที่จะหมายถึง "มักจะใช้ตัวแบ่ง" ในกรณีที่โปรแกรมเมอร์บางคนเพิ่มใหม่caseในตอนท้ายของคุณswitchโดยไม่ตรวจสอบว่าbreakมีอยู่ (มันจะเป็นความผิดของโปรแกรมเมอร์ที่ แต่ยังคงปลอดภัยถ้าเหตุผลใด ๆ เพราะคุณอาจเป็นโปรแกรมเมอร์ใน 6 เดือน)
SJuan76

@ SJuan76 ใช่ฉันเห็นด้วยดีกว่าปลอดภัยกว่าขออภัยถ้าคุณต้องการที่จะป้องกันข้อผิดพลาดในอนาคตคุณต้องรวมไว้ในตอนท้าย
Suvarnabhumia Pattayil

1
ด้วยเหตุผลในใจคุณอาจจะโต้แย้งว่าจะมี, ในตอนท้ายของอาร์เรย์เสมอในกรณีที่มีการใส่ค่าใหม่ อย่างไรก็ตามที่แบ่งรหัสบางและโดยทั่วไปมีลักษณะน่าเกลียด :)
โรบิน Castlin

1
@ Robin การใส่เครื่องหมายจุลภาคแตกต่างกัน หากไม่มีและมีคนเพิ่มค่าใหม่ให้กับอาร์เรย์แล้วพวกเขาจะได้รับข้อผิดพลาดในการรวบรวม อย่างไรก็ตามจะไม่มีข้อผิดพลาดในการคอมไพล์หากคำสั่ง case ก่อนหน้านี้ไม่มีตัวแบ่ง - ดังนั้นจึงเป็นไปได้ที่จะพลาดและทำให้เกิดข้อผิดพลาดรันไทม์
Keith Miller

@RobinCastlin ,มีให้ภาษาที่ได้รับอนุญาตให้คุณใส่ กรณีdefaultถูกออกแบบมาให้เป็นกรณีสุดท้าย บางทีภาษาอาจจะพิจารณาbreakหลังจากมันเป็นข้อผิดพลาด สันนิษฐานว่าbreakได้รับอนุญาตให้เป็นตัวแยกความแตกต่างระหว่างสองกรณีเท่านั้น
สุวรรณชา Pattayil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.