ในระหว่างการตรวจสอบโค้ดเมื่อเร็ว ๆ นี้ฉันถูกขอให้ใส่default
เคสในไฟล์ทั้งหมดทุกที่ที่switch
บล็อกถูกใช้แม้ว่าจะไม่มีอะไรทำdefault
ก็ตาม นั่นหมายความว่าฉันต้องใส่default
เคสและไม่เขียนอะไรเลย
นี่เป็นสิ่งที่ถูกต้องหรือไม่ มันจะมีจุดประสงค์อะไร
ในระหว่างการตรวจสอบโค้ดเมื่อเร็ว ๆ นี้ฉันถูกขอให้ใส่default
เคสในไฟล์ทั้งหมดทุกที่ที่switch
บล็อกถูกใช้แม้ว่าจะไม่มีอะไรทำdefault
ก็ตาม นั่นหมายความว่าฉันต้องใส่default
เคสและไม่เขียนอะไรเลย
นี่เป็นสิ่งที่ถูกต้องหรือไม่ มันจะมีจุดประสงค์อะไร
คำตอบ:
ดูเหมือนว่ามีสามกรณีที่default
ไม่จำเป็นต้องมีคำสั่ง:
กรณีไม่มีอื่น ๆ ที่เหลือเพราะมีชุด จำกัด switch case
ของค่าที่ป้อน แต่สิ่งนี้อาจเปลี่ยนแปลงตามเวลา (โดยบังเอิญหรือไม่ตั้งใจ) และมันเป็นการดีdefault case
หากมีสิ่งใดเปลี่ยนแปลง _ คุณสามารถบันทึกหรือเตือนผู้ใช้เกี่ยวกับค่าที่ไม่ถูกต้อง
คุณรู้ว่าswitch case
จะใช้อย่างไรและที่ไหนและจะป้อนค่าใด อีกครั้งสิ่งนี้อาจเปลี่ยนแปลงและอาจจำเป็นต้องมีการประมวลผลเพิ่มเติม
กรณีอื่น ๆ ไม่จำเป็นต้องมีการประมวลผลพิเศษ หากเป็นกรณีนี้ฉันคิดว่าคุณถูกขอให้เพิ่ม a default case
เนื่องจากเป็นรูปแบบการเข้ารหัสที่ยอมรับได้และทำให้โค้ดของคุณอ่านง่ายขึ้น
สองกรณีแรกขึ้นอยู่กับสมมติฐาน ดังนั้น (สมมติว่าคุณทำงานในทีมที่ไม่เล็กเนื่องจากคุณมีบทวิจารณ์โค้ดปกติ) คุณจึงไม่สามารถตั้งสมมติฐานเหล่านั้นได้ คุณไม่รู้ว่าใครจะทำงานกับรหัสของคุณหรือโทรไปยังฟังก์ชั่น / วิธีการเรียกใช้ในรหัสของคุณ ในทำนองเดียวกันคุณอาจต้องทำงานกับรหัสของคนอื่น การมีรูปแบบการเข้ารหัสเหมือนกันจะช่วยให้สามารถจัดการกับรหัสของใครบางคน (รวมถึงของคุณ) ได้ง่ายขึ้น
throw new IllegalStateException("Unrecognised case "+myEnum)
ที่แสดงให้คุณทราบว่าเกิดอะไรขึ้น
else
ประโยคตลอดif/else if
แม้ว่าคุณจะรู้ว่าไม่ควรเกิดขึ้น? ดูเหมือนจะไม่เป็นความคิดที่ดีสำหรับฉัน ...
นี่เป็นสิ่งที่ถูกต้องใช่ไหม มันจะมีจุดประสงค์อะไร
ไม่ใช่เรื่องแปลกที่มาตรฐานการเข้ารหัสของ บริษัท จะต้องมีตัวพิมพ์เล็กสำหรับswitch
คำสั่งทั้งหมด switch
เหตุผลหนึ่งก็คือว่ามันจะทำให้มันง่ายสำหรับผู้อ่านที่จะหาจุดสิ้นสุดของ อีกเหตุผลที่น่าจะดีกว่าคือการทำให้คุณคิดเป็นวินาทีเกี่ยวกับสิ่งที่รหัสของคุณควรทำเมื่อเงื่อนไขไม่ตรงกับความคาดหวังของคุณ โดยไม่คำนึงถึงเหตุผลสำหรับความต้องการหากเป็นมาตรฐานของ บริษัท คุณควรปฏิบัติตามเว้นแต่จะมีเหตุผลที่ไม่ควรทำ
หากคุณเชื่อว่าswitch
กรณีรวมของคุณสำหรับทุกเงื่อนไขที่เป็นไปได้สิ่งที่ดีที่ต้องทำคือการใส่assert
คำสั่งในกรณีเริ่มต้น ด้วยวิธีนี้เมื่อมีคนเปลี่ยนรหัสและเพิ่มเงื่อนไขที่คุณswitch
ไม่ครอบคลุมพวกเขาจะกดassert
และรู้ว่าพวกเขาจำเป็นต้องจัดการส่วนนั้นของรหัส
หากคุณswitch
ครอบคลุมเงื่อนไขที่เป็นไปได้เพียงบางอย่างเท่านั้น แต่ไม่มีสิ่งใดที่ต้องทำเป็นพิเศษสำหรับผู้อื่นคุณสามารถปล่อยให้กรณีเริ่มต้นว่างเปล่าได้ เป็นความคิดที่ดีที่จะเพิ่มความคิดเห็นในกรณีนั้นเพื่อระบุว่ากรณีเริ่มต้นว่างเปล่าโดยเจตนาเพราะเงื่อนไขที่กระทบไม่จำเป็นต้องมีงานใด ๆ
หากคุณ "สลับ" ในประเภทการแจงนับล้วนเป็นสิ่งที่อันตรายที่จะมีทางเลือกเริ่มต้น เมื่อคุณเพิ่มค่าในประเภทการแจงนับในภายหลังคอมไพเลอร์จะเน้นสวิตช์ที่ไม่มีค่าใหม่ หากคุณมีส่วนเริ่มต้นที่นั่นคอมไพเลอร์จะเงียบและคุณอาจพลาด
ในหลายประการคำถามนี้เป็นเช่นเดียวกับมักจะถามว่าฉันจะต้องelse
เป็นไปตามข้อในตอนท้ายของนั้นif
/else if
บันไดที่ครอบคลุมทุกตัวเลือก
คำตอบคือการพูดทางวากยสัมพันธ์ไม่มีคุณไม่ได้ แต่มี ...
default
ประโยคสามารถจะมีสำหรับ (อย่างน้อย) เหตุผลสองประการคือ
otherwise
จากเคส ไม่มีเหตุผลใด ๆ สำหรับการไม่รวมสิ่งเหล่านี้ในซอร์สโค้ดปรัชญาของฉันค่อนข้างเรียบง่าย - ประเมินสถานการณ์กรณีที่เลวร้ายที่สุดของสองตัวเลือกและดำเนินการอย่างปลอดภัยที่สุด ในกรณีที่ว่างเปล่าelse
หรือdefault
ส่วนคำสั่งตัวเลือกกรณีที่แย่ที่สุดคือ:
Overdramatic? อาจจะ ... แต่แล้วซอฟต์แวร์ของฉันก็มีโอกาสที่จะฆ่าผู้คนถ้ามันผิดพลาด ฉันไม่อยากเสี่ยง
นอกจากนี้แนวทางMISRA-C {ดูโปรไฟล์สำหรับการติดต่อ} แนะนำdefault
ข้อสำหรับทุก ๆ ข้อswitch
else
if
แต่อย่างที่คุณพูดไม่มันไม่ใช่
Java ไม่ได้บังคับให้คุณมีคำสั่ง 'เริ่มต้น' แต่เป็นวิธีที่ดีที่จะมีหนึ่งตลอดเวลาแม้ว่ารหัสอาจจะไม่สามารถเข้าถึงได้ (ตอนนี้) นี่คือเหตุผลไม่กี่:
โดยการมีข้อเริ่มต้นที่เข้าไม่ถึงคุณแสดงให้ผู้อ่านของรหัสของคุณที่คุณพิจารณาค่าและรู้ว่าสิ่งที่คุณกำลังทำ นอกจากนี้คุณยังอนุญาตให้มีการเปลี่ยนแปลงในอนาคตเช่นตัวอย่าง: เพิ่มค่า enum ใหม่สวิตช์ไม่ควรละเว้นค่าใหม่ คุณสามารถโยนข้อยกเว้นที่นั่นแทนหรือทำอย่างอื่น
เมื่อต้องการรับค่าที่ไม่คาดคิด (ในกรณีที่คุณไม่ได้เปิด enum) ที่ส่งผ่านอาจเป็นค่าที่มากกว่าหรือน้อยกว่าที่คุณคาดไว้
เพื่อจัดการการกระทำ 'เริ่มต้น' - ตำแหน่งที่สวิตช์ใช้สำหรับพฤติกรรมพิเศษ ตัวอย่างเช่นตัวแปรอาจถูกประกาศภายนอกสวิตช์ แต่ไม่ได้กำหนดค่าเริ่มต้นและแต่ละกรณีจะกำหนดค่าเริ่มต้นให้เป็นสิ่งที่แตกต่างกัน ค่าเริ่มต้นในกรณีนี้สามารถเริ่มต้นเป็นค่าเริ่มต้นได้ดังนั้นรหัสในทันทีหลังจากที่สวิตช์ไม่มีข้อผิดพลาด / เกิดข้อยกเว้น
แม้ว่าคุณตัดสินใจที่จะไม่ใส่อะไรในค่าเริ่มต้น (ไม่มีข้อยกเว้นการบันทึก ฯลฯ ) แม้แต่ความคิดเห็นที่บอกว่าคุณได้พิจารณาว่าการเริ่มต้นจริงจะไม่เกิดขึ้นอาจช่วยให้อ่านรหัสได้ แต่นั่นก็ขึ้นอยู่กับความชอบส่วนตัว
ฉันจะเพิ่มว่ามันขึ้นอยู่กับปรัชญาของภาษาที่คุณใช้ ในตัวอย่างของ Erlang ซึ่งเป็นวิธีการทั่วไปในการ 'ปล่อยให้มันล้มเหลว' คุณจะไม่กำหนดกรณีเริ่มต้น แต่ให้case
ข้อความของคุณแจ้งข้อผิดพลาดหากเกิดสถานการณ์ที่ไม่รองรับ
คุณควรมีค่าเริ่มต้นเสมอเว้นแต่คุณจะได้กล่าวถึงทุกกรณี ไม่มีค่าใช้จ่ายใด ๆ และเป็นการประกันความล้มเหลวในการรักษาคำสั่งสวิตช์ของคุณในโปรแกรมที่กำลังพัฒนา
หากคุณแน่ใจจริงๆว่าคุณไม่สนใจกรณีอื่น ๆ ค่าเริ่มต้น: break; // ไม่สนใจ แต่ค่าเริ่มต้นควรเป็นค่าเริ่มต้นเช่นโยนข้อผิดพลาดใหม่ ("ค่าที่ไม่คาดคิด");
ในทำนองเดียวกันคุณไม่ควร "เลื่อนผ่าน" โครงสร้างตัวพิมพ์เล็ก ๆ น้อย ๆ โดยไม่เพิ่มความคิดเห็นไปยังเอฟเฟกต์ที่คุณตั้งใจจะใช้ Java เข้าใจผิดในขั้นตอนการออกแบบ
พิจารณา
enum Gender
{
MALE ,
FEMALE ;
}
และ
void run ( Gender g )
{
switch ( g )
{
case MALE :
// code related to males
break ;
default :
assert Gender . FEMALE . equals ( g ) ;
// code related to females
break ;
}
}
ฉันจะโต้แย้งว่านี่ดีกว่าการมีกรณีเพศชาย, คดีหญิงและกรณีเริ่มต้นที่ส่งข้อยกเว้น
ในระหว่างขั้นตอนการทดสอบคอมพิวเตอร์จะตรวจสอบว่า g เป็นหญิงหรือไม่ ในระหว่างการผลิตการตรวจสอบจะถูกละเว้น (ใช่ microoptimization!)
ที่สำคัญคุณจะต้องรักษาเป้าหมายของคุณให้ครอบคลุมรหัส 100% หากคุณเขียนกรณีเริ่มต้นที่ส่งข้อยกเว้นคุณจะทดสอบได้อย่างไร
Gender . FEMALE . equals ( FEMALE ) ;
ประเมินfalse
? คุณหมายถึงGender.FEMALE.equals (g)
แต่เนื่องจากคุณสามารถอ้างอิงถึง enums ที่มีความเสถียรคุณจึงสามารถเขียนg == Gender.FEMALE
ได้ 4. (ความเห็นส่วนตัว) รหัสดังกล่าวนั้นยากต่อการอ่านและจะทำให้เกิดข้อผิดพลาดที่สับสนเล็กน้อย