Tại sao ngôn ngữ không sử dụng thông báo rõ ràng về các câu lệnh chuyển đổi?


17

Tôi đã đọc Tại sao chúng ta phải sử dụng breaktrong switch? và điều đó khiến tôi băn khoăn tại sao việc bỏ qua ngầm được cho phép trong một số ngôn ngữ (như PHP và JavaScript), trong khi không có hỗ trợ (AFAIK) cho thông qua rõ ràng.

Nó không giống như một từ khóa mới sẽ cần phải được tạo ra, như continuelà hoàn toàn phù hợp, và sẽ giải quyết bất kỳ vấn đề mơ hồ nào cho dù tác giả có ý định cho một trường hợp thông qua.

Biểu mẫu hiện được hỗ trợ là:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ... //ambiguous, was break forgotten?
    case 3:
        ...
        break;
    default:
        ...
        break;
}

Trong khi đó, nó sẽ có ý nghĩa đối với nó được viết là:

switch (s) {
    case 1:
        ...
        break;
    case 2:
        ...
        continue; //unambiguous, the author was explicit
    case 3:
        ...
        break;
    default:
        ...
        break;
}

Đối với mục đích của câu hỏi này, hãy bỏ qua vấn đề liệu có hay không thông qua một phong cách mã hóa tốt.

Có ngôn ngữ nào tồn tại cho phép thông qua và đã làm cho nó rõ ràng không?

Có bất kỳ lý do lịch sử nào switchcho phép rơi vào ẩn thay vì rõ ràng không?


4
C # yêu cầu bạn phải rõ ràng goto case, vì vậy tiền đề của câu hỏi của bạn là một chút sai.
pdr

1
@pdr, tôi đã hỏi rất rõ ràng nếu có bất kỳ ngôn ngữ nào đã được hỗ trợ thông qua, tôi không biết về goto caseC #.
zzzzBov

Vâng, xin lỗi, tôi đã bỏ lỡ rằng có hai phần cho câu hỏi của bạn. Thật không may, cụm từ như vậy, tôi đang bỏ phiếu để đóng vì nó rất gần với một câu hỏi thăm dò ý kiến. Sẽ có rất nhiều câu trả lời đúng.
pdr

C # cũng cho phép bạn có nhiều nhãn chia sẻ cùng một danh sách câu lệnh, loại bỏ một số tình huống cần phải thông qua. Đối với phần còn lại, nó có goto case, như pdr đề cập.
Brian

Câu trả lời:


20

Nó chủ yếu mang tính lịch sử, hầu hết các ngôn ngữ chỉ sao chép những gì C đã làm.

Lý do mà C đã làm theo cách đó là vì những người tạo ra C dự định các câu lệnh chuyển đổi để dễ dàng tối ưu hóa thành một bảng nhảy. Đây cũng là lý do mà C giới hạn các câu lệnh chuyển thành giá trị tích phân.

Trong một bảng nhảy, chương trình sẽ tính toán vị trí cần nhảy để dựa vào biểu thức. Chương trình sẽ nhảy đến điểm đó và sau đó tiếp tục thực hiện từ thời điểm đó. Nếu bạn muốn bỏ qua phần còn lại của bảng, bạn phải bao gồm một bước nhảy đến cuối bảng. C sử dụng các breakcâu lệnh rõ ràng để có sự tương ứng trực tiếp với cấu trúc này.


7
Một lưu ý nhỏ, trong cuốn sách "Expert C Lập trình" của mình, Peter van der Linden đã đề cập rằng trong khi ông làm việc cho Sun trên trình biên dịch C của họ, khoảng ~ 97% các trường hợp chuyển đổi có breakvà chỉ có ít hơn 3% bị rơi . Sau đó, ông đã sử dụng điều này như một ví dụ rằng hành vi rơi vào mặc định là phản trực giác và tốt hơn là nên đảo ngược (sử dụng một từ khóa để chỉ ra sự rơi xuống rõ ràng). Ồ, và cuốn sách thực sự tuyệt vời trong việc giải thích những điều kỳ lạ khác của C, một số trong số đó được tìm thấy trong C ++ và thậm chí trong C # và Java nữa! Tất cả đều bắt nguồn từ B và BCPL. :)
zxcdw

3
Có những ngôn ngữ lập trình mà thông qua là rõ ràng, như c # ( msdn.microsoft.com/en-us/l Library / 06tc147t ( v = vs.71 ) .aspx ). Mặt khác, phá vỡ cũng rõ ràng trong c #.
linkerro

@zxcdw: Quá tệ, không có cách nào một chú chim nhỏ có thể quay ngược thời gian và đề nghị rằng bất kỳ nhãn nào được đánh dấu case, ngoại trừ nhãn đầu tiên, nên được tự động thêm tiền tố break, nhưng những nhãn hiệu được đánh dấu +case(hoặc một số nhà chỉ định khác) không nên. Điều đó sẽ dễ dàng cho một trình biên dịch xử lý và cho phép các lợi thế ngữ nghĩa của sự sắp xếp hiện tại, trong khi loại bỏ nhiều dòng mã.
supercat

7

Go cho phép dự phòng rõ ràng bằng cách sử dụng fallthroughtừ khóa (ngắt là ẩn, nhưng có thể rõ ràng):

switch val {
case 1: // breaks
case 2:
    fallthrough
case 3:
    goto 
case 4, 5, 6: // equivalent to defining individual cases with explicit fallthough
    break // unnecessary
default:
}

Đây là bit có liên quan từ đi hiệu quảđặc tả ngôn ngữ .

Tôi không nghĩ bạn có thể sử dụng gotođể đi đến một trường hợp cụ thể, nhưng bạn có thể tạo nhãn bên trong vỏ và sử dụng gotonhư bình thường.

Là một phần thưởng, Go cho phép bạn sử dụng các biểu thức nhị phân, chuỗi hoặc loại trong một công tắc như các câu lệnh tình huống.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.