Khi nào thì thích hợp để sử dụng câu lệnh chuyển đổi rơi (cổ điển)? Việc sử dụng như vậy có được khuyến khích và khuyến khích hay nên tránh bằng mọi giá?
Khi nào thì thích hợp để sử dụng câu lệnh chuyển đổi rơi (cổ điển)? Việc sử dụng như vậy có được khuyến khích và khuyến khích hay nên tránh bằng mọi giá?
Câu trả lời:
Đây là một ví dụ nơi nó sẽ hữu ích.
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;
}
Loại điều này (trong đó một trường hợp bao gồm trường hợp khác) là khá hiếm, tôi nghĩ, đó là lý do tại sao một số ngôn ngữ mới hơn không cho phép chuyển đổi hoặc yêu cầu cú pháp đặc biệt cho nó.
// INTENTIONAL FALL THROUGH HERE
bình luận tất cả các mũ cần thiết .
GetItemsForLevel(Info)
cuộc gọi GetItemsForLevel(Warning)
và cứ thế.
Tôi sử dụng chúng khi chức năng nhất định phải được áp dụng cho nhiều hơn một giá trị. Ví dụ: giả sử bạn có một đối tượng có thuộc tính được gọi là operCode. Nếu mã bằng 1, 2, 3 hoặc 4, bạn muốn startOperationX (). Nếu là 5 hoặc 6, bạn muốn startOperationY () và 7 bạn startOperationZ (). Tại sao có 7 trường hợp hoàn chỉnh với chức năng và nghỉ khi bạn có thể sử dụng thông qua?
Tôi nghĩ rằng nó hoàn toàn hợp lệ trong một số trường hợp nhất định, đặc biệt là nếu nó tránh được 100 câu lệnh if-other. =)
switch
với nhiều case
s được gắn vào cùng một mã. Điều đó khác với một lần rơi, trong đó việc xử tử người này case
tiếp tục vào vụ tiếp theo vì thiếu một người break
giữa họ.
Trường hợp rơi qua là hoàn toàn tốt đẹp. Tôi thường thấy rằng một phép liệt kê được sử dụng ở nhiều nơi và khi bạn không cần phân biệt một số trường hợp thì việc sử dụng logic rơi sẽ dễ dàng hơn.
Ví dụ (lưu ý các ý kiến giải thích):
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;
}
}
Tôi thấy loại sử dụng này hoàn toàn chấp nhận được.
case X: case Y: doSomething()
và case X: doSomething(); case Y: doAnotherThing()
. Trong lần đầu tiên, ý định là khá rõ ràng, trong khi trong lần thứ hai, sự rơi qua có thể có chủ ý hoặc không. Theo kinh nghiệm của tôi, ví dụ đầu tiên không bao giờ kích hoạt bất kỳ cảnh báo nào trong trình biên dịch / trình phân tích mã, trong khi ví dụ thứ hai thì không. Cá nhân, tôi sẽ chỉ gọi ví dụ thứ hai là "rơi qua" - mặc dù không chắc chắn về một định nghĩa "chính thức".
Nó phụ thuộc vào:
Hai vấn đề chính liên quan đến việc để một trường hợp rơi vào trường hợp tiếp theo là:
Nó làm cho mã của bạn phụ thuộc vào thứ tự của các báo cáo trường hợp. Đó không phải là trường hợp nếu bạn không bao giờ rơi vào, và nó thêm một mức độ phức tạp thường không được chào đón.
Không rõ ràng rằng mã cho một trường hợp bao gồm mã cho một hoặc nhiều trường hợp tiếp theo.
Một số nơi rõ ràng cấm rơi qua. Nếu bạn không làm việc ở một nơi như vậy, và nếu bạn cảm thấy thoải mái với việc luyện tập và nếu việc phá mã trong câu hỏi sẽ không gây ra bất kỳ đau khổ thực sự nào, thì đó có thể không phải là điều tồi tệ nhất trên thế giới. Tuy nhiên, nếu bạn làm điều đó, hãy chắc chắn để đưa ra một nhận xét thu hút sự chú ý gần đó để cảnh báo những người đến sau (bao gồm cả tương lai bạn).
Đây là một ví dụ nhanh chóng (không được thừa nhận (không xử lý đặc biệt năm nhuận)) về việc rơi vào làm cho cuộc sống của tôi đơn giản hơn:
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;
}
Nếu tôi cảm thấy cần phải đi từ trường hợp này sang trường hợp khác (hiếm, phải thừa nhận), tôi thích phải rất rõ ràng và goto case
tất nhiên, điều đó giả định rằng ngôn ngữ của bạn hỗ trợ nó.
Bởi vì thông thường rất hiếm và rất dễ bị bỏ qua khi đọc mã, tôi cảm thấy nó phù hợp để rõ ràng - và một chiếc goto, ngay cả khi nó là một trường hợp, nên nổi bật như ngón tay cái đau.
Nó cũng giúp tránh các lỗi có thể xảy ra khi các báo cáo trường hợp được sắp xếp lại.