Чому мови не використовують явні заяви про перехід на комутатор?


17

Я читав Чому ми повинні використовувати breakв switch? , і це змусило мене замислитись про те, чому дозволено неявне проходження на деяких мовах (таких як PHP та JavaScript), поки немає підтримки (AFAIK) для явного проходу.

Це не так, як потрібно було б створити нове ключове слово, як це continueбуло б цілком доречно, і воно вирішило б питання щодо неоднозначності щодо того, чи мав на увазі автор на випадок випадку.

На даний момент підтримується форма:

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

Тоді як було б сенс його писати так:

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

Для цілей цього питання дозволяємо ігнорувати питання про те, чи є прохідні файли хорошим стилем кодування чи ні.

Чи існують якісь мови, які дозволяють пропускати і роблять це явним?

Чи є якісь історичні причини, які switchдозволяють мати неявне проходження замість явних?


4
C # вимагає, щоб ви були чіткими goto case, тому передумова вашого питання трохи неправильна.
пдр

1
@pdr, я дуже чітко запитав, чи є якісь мови, які вже підтримують пропуск, про що мені не відомо goto caseв C #.
zzzzBov

Так, вибачте, я пропустив, що до вашого питання було дві частини. На жаль, сформульований так, як є, я голосую за закриття, оскільки це дуже близько до опитування. Правильних відповідей буде багато.
пдр

Також C # дозволяє вам мати декілька міток, які діляться одним списком висловлювань, що видаляє деякі ситуації, які потребують проходження. Для решти, це goto case, як згадується pdr.
Брайан

Відповіді:


20

Це перш за все історично, більшість мов просто скопіювали те, що зробив C

Причина того, що C зробив це таким чином, полягає в тому, що творці C задумали перекладати заяви, щоб їх було легко оптимізувати в таблицю стрибків. Це також причина того, що C обмежує переключення операторів на цілісні значення.

У таблиці стрибків програма обчислить, в яку позицію перейти, виходячи з виразу. Програма перейде до цієї точки, а потім продовжить виконання з цієї точки. Якщо ви хочете пропустити решту таблиці, вам потрібно включити стрибок до кінця таблиці. C використовує явні breakтвердження так, що існує пряма відповідність цій конструкції.


7
Як невеличке зауваження, у своїй книзі "Експертне програмування C" Пітер ван дер Лінден згадує, що, працюючи над Sun над їх компілятором C, десь ~ 97% випадків комутації містилися, breakі лише менше 3% були пропущеними . Потім він застосував це як приклад того, що поведінка за промовчанням за замовчуванням є протиінтуїтивно зрозумілою, і було б краще бути зворотною (використовуйте ключове слово для позначення явного проходу). О, і книга справді чудово пояснює і інші дивацтва C, деякі з яких є у C ++ і навіть у C # та Java! Це все корінням у B та BCPL. :)
zxcdw

3
Існують мови програмування, де пропуск є явним, наприклад c # ( msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx ). З іншого боку, порушення також явне в c #.
linkerro

@zxcdw: Шкода, що маленький пташиний спосіб не міг би повернутися у часі, і припустити, що будь-яка мітка case, окрім першої, має бути автоматично встановлена ​​з префіксом break, але ті, що позначені +case(або якийсь інший такий позначник), не повинні. Це було б легко для компілятора в обробці і дозволило б мати смислові переваги цього розташування, усуваючи при цьому багато рядків коду.
supercat

7

Go дозволяє чітке проходження за допомогою fallthroughключового слова (перерва неявна, але може бути явною):

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:
}

Ось відповідний біт від ефективного переходу та специфікації мови .

Я не думаю, що ви можете використовувати gotoдля переходу до конкретного випадку, але ви можете зробити мітку всередині корпусу і використовувати gotoяк- небудь звичайне.

Як бонус, Go дозволяє використовувати бінарні вирази, рядки або типи в комутаторі як заяви про регістри.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.