เมื่อใดที่เหมาะสมที่จะใช้คำสั่ง switch-fall (classic) มีการแนะนำและสนับสนุนการใช้งานดังกล่าวหรือไม่และควรหลีกเลี่ยงค่าใช้จ่ายทั้งหมดหรือไม่?
เมื่อใดที่เหมาะสมที่จะใช้คำสั่ง switch-fall (classic) มีการแนะนำและสนับสนุนการใช้งานดังกล่าวหรือไม่และควรหลีกเลี่ยงค่าใช้จ่ายทั้งหมดหรือไม่?
คำตอบ:
นี่คือตัวอย่างที่มันจะมีประโยชน์
public Collection<LogItems> GetAllLogItems(Level level) {
Collection<LogItems> result = new Collection<LogItems>();
switch (level) {
// Note: fall through here is INTENTIONAL
case All:
case Info:
result.Add(GetItemsForLevel(Info));
case Warning:
result.Add(GetItemsForLevel(Warning));
case Error:
result.Add(GetItemsForLevel(Error));
case Critical:
result.Add(GetItemsForLevel(Critical));
case None:
}
return result;
}
ฉันคิดว่าสิ่งนี้ (ซึ่งกรณีหนึ่งรวมถึงอีกกรณีหนึ่ง) ค่อนข้างหายากซึ่งเป็นสาเหตุที่ภาษาใหม่บางภาษาไม่อนุญาตให้มีการตกหล่นหรือต้องใช้ไวยากรณ์พิเศษสำหรับมัน
// INTENTIONAL FALL THROUGH HERE
ความคิดเห็นที่จำเป็นสำหรับตัวพิมพ์ใหญ่ทั้งหมด
GetItemsForLevel(Info)
เรียกใช้GetItemsForLevel(Warning)
และอื่น ๆ
ฉันใช้พวกเขาเมื่อต้องใช้การทำงานบางอย่างกับค่ามากกว่าหนึ่งค่า ตัวอย่างเช่นสมมติว่าคุณมีวัตถุที่มีคุณสมบัติชื่อ operationCode ถ้ารหัสเท่ากับ 1, 2, 3 หรือ 4 คุณต้องการ startOperationX () ถ้าเป็น 5 หรือ 6 คุณต้องการ startOperationY () และ 7 ที่คุณ startOperationZ () เหตุใดจึงมี 7 กรณีที่สมบูรณ์พร้อมฟังก์ชั่นและตัวแบ่งเมื่อคุณสามารถใช้ fall-throughs ได้?
ฉันคิดว่ามันใช้ได้อย่างสมบูรณ์ในบางสถานการณ์โดยเฉพาะอย่างยิ่งถ้ามันหลีกเลี่ยงคำสั่ง if-else 100 ข้อ =)
switch
มีหลายcase
s เชื่อมโยงกับรหัสเดียวกัน นั่นแตกต่างจากการล้มลงโดยที่การประมวลผลอันใดอันหนึ่งcase
ดำเนินต่อไปสู่อีกอันหนึ่งเนื่องจากขาดbreak
ระหว่างพวกเขา
ฉันเคยใช้มันเป็นครั้งคราวฉันคิดว่ามันเหมาะสมกับการใช้งานเสมอ - แต่เมื่อรวมกับความคิดเห็นที่เหมาะสม
กรณีฤดูใบไม้ร่วงผ่านไปได้อย่างสมบูรณ์แบบ ฉันมักจะพบว่ามีการใช้การแจงนับในหลาย ๆ ที่และเมื่อคุณไม่จำเป็นต้องแยกแยะความแตกต่างในบางกรณีการใช้ลอจิกแบบหล่นผ่านก็ง่ายกว่า
ตัวอย่างเช่น (สังเกตความคิดเห็นที่อธิบาย):
public boolean isAvailable(Server server, HealthStatus health) {
switch(health) {
// Equivalent positive cases
case HEALTHY:
case UNDER_LOAD:
return true;
// Equivalent negative cases
case FAULT_REPORTED:
case UNKNOWN:
case CANNOT_COMMUNICATE:
return false;
// Unknown enumeration!
default:
LOG.warn("Unknown enumeration " + health);
return false;
}
}
ฉันพบว่าการใช้งานประเภทนี้เป็นที่ยอมรับอย่างสมบูรณ์
case X: case Y: doSomething()
case X: doSomething(); case Y: doAnotherThing()
ในครั้งแรกความตั้งใจค่อนข้างชัดเจนในขณะที่ในสองการตกผ่านอาจมีเจตนาหรือไม่ จากประสบการณ์ของฉันตัวอย่างแรกไม่เคยเรียกใช้คำเตือนใด ๆ ในคอมไพเลอร์ / ตัววิเคราะห์โค้ดในขณะที่คำสั่งที่สองทำ โดยส่วนตัวแล้วฉันจะเรียกตัวอย่างที่สองว่า "fall through" - ไม่แน่ใจเกี่ยวกับคำจำกัดความ "เป็นทางการ"
ขึ้นอยู่กับ:
ปัญหาหลักสองประการที่เกี่ยวข้องกับการอนุญาตให้เคสหนึ่งเคสผ่านไปยังเคสถัดไปคือ:
มันทำให้รหัสของคุณขึ้นอยู่กับคำสั่งของคำสั่งกรณี นี่ไม่ใช่กรณีถ้าคุณไม่เคยผ่านและเพิ่มระดับของความซับซ้อนที่มักจะไม่พอใจ
ไม่ชัดเจนว่ารหัสสำหรับหนึ่งกรณีรวมถึงรหัสสำหรับหนึ่งหรือหลายกรณีที่ตามมา
บางสถานที่ห้ามมิให้ผ่านอย่างชัดเจน หากคุณไม่ได้ทำงานในสถานที่ดังกล่าวและหากคุณพอใจกับการฝึกฝนและหากการทำลายรหัสที่เป็นปัญหาจะไม่ก่อให้เกิดความทุกข์ทรมานอย่างแท้จริงมันอาจไม่ใช่สิ่งที่เลวร้ายที่สุดในโลก หากคุณทำเช่นนั้นอย่าลืมใส่ความคิดเห็นที่ดึงดูดความสนใจในบริเวณใกล้เคียงเพื่อเตือนผู้ที่มาภายหลัง (รวมถึงอนาคตของคุณด้วย)
นี่คือตัวอย่างรวดเร็ว (ไม่สมบูรณ์เป็นที่ยอมรับ (ไม่มีการจัดการกระโดดปีพิเศษ)) จากการล้มทำให้ชีวิตของฉันง่ายขึ้น:
function get_julian_day (date) {
int utc_date = date.getUTCDate();
int utc_month = date.getUTCMonth();
int julian_day = 0;
switch (utc_month) {
case 11: julian_day += 30;
case 10: julian_day += 31;
case 9: julian_day += 30;
case 8: julian_day += 31;
case 7: julian_day += 31;
case 6: julian_day += 30;
case 5: julian_day += 31;
case 4: julian_day += 30;
case 3: julian_day += 31;
case 2: julian_day += 28;
case 1: julian_day += 31;
default: break;
}
return julian_day + utc_date;
}
หากฉันรู้สึกว่าจำเป็นต้องเปลี่ยนจากกรณีหนึ่งไปอีกกรณีหนึ่ง (หายากเป็นที่ยอมรับ) ฉันชอบที่จะอธิบายอย่างชัดเจนและgoto case
แน่นอนว่าภาษาของคุณรองรับ
เนื่องจากการตกหลุมรักเป็นเรื่องธรรมดามากและง่ายมากที่จะมองข้ามในขณะที่อ่านรหัสฉันรู้สึกว่ามันเหมาะสมที่จะชัดเจน - และการข้ามไปแม้ว่าจะเป็นกรณีควรโดดเด่นเหมือนนิ้วหัวแม่มือเจ็บ
นอกจากนี้ยังช่วยหลีกเลี่ยงข้อบกพร่องที่อาจเกิดขึ้นเมื่อคำสั่ง case ถูกจัดลำดับใหม่