Запрос оператора switch [duplicate]

Я хотел бы добавить одну вещь к отличному ответу chazomaticus :

Не забудьте также тег META (например, или HTML4 или XHTML-версия этого файла ):


Это кажется тривиальным, но IE7 дал мне проблемы с этим раньше.

Я делал все правильно; база данных, соединение с базой данных и HTTP-заголовок Content-Type были настроены на UTF-8, и она отлично работала во всех других браузерах, но Internet Explorer по-прежнему настаивал на использовании «западноевропейской» кодировки.

It оказалось, что на странице отсутствует метка META. Добавление этого решения проблемы.

Правка:

У W3C фактически есть довольно большой раздел , посвященный I18N . У них есть ряд статей, связанных с этой проблемой & ndash; описывая HTTP, (X) HTML и CSS сторону вещей:

Они рекомендуют использовать как HTTP-заголовок, так и HTML метатег (или объявление XML в случае XHTML служил XML).

75
задан Paul Bellora 7 June 2013 в 21:33
поделиться

16 ответов

Иногда полезно иметь несколько случаев, связанных с одним и тем же кодовым блоком, например

case 'A':
case 'B':
case 'C':
    doSomething();
    break;

case 'D':
case 'E':
    doSomethingElse();
    break;

и т. д. Только пример.

По моему опыту, обычно это плохой стиль, чтобы «провалиться» и иметь несколько блоков кода для одного случая, но в некоторых ситуациях его использование может быть использовано.

81
ответ дан WildCrustacean 28 August 2018 в 18:45
поделиться

Исторически , это потому, что case по существу определял label, также известный как целевая точка вызова goto. Оператор switch и связанные с ним случаи действительно представляют собой многовекторную ветвь с множеством потенциальных точек входа в поток кода.

Все сказанное было отмечено почти бесконечное число раз, когда break почти всегда поведение по умолчанию, которое вы предпочитаете в конце каждого случая.

29
ответ дан Bob Cross 28 August 2018 в 18:45
поделиться

Почему компилятор автоматически не помещает инструкции break после каждого кодового блока в коммутаторе?

Оставляя в стороне хороший желание быть способным использовать идентичный блок для нескольких случаев (который может быть специально обложен) ...

Это по историческим причинам? Когда вам нужно выполнить несколько блоков кода?

Это в основном для совместимости с C и, возможно, является древним взломом из старых дней, когда ключевые слова goto бродили по земле. Например, делает некоторые удивительные вещи, такие как Устройство Даффа , но является ли это точкой в ​​его пользу или против ... в лучшем случае.

5
ответ дан Donal Fellows 28 August 2018 в 18:45
поделиться

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

Представьте, что у вас есть три состояния, которые ждут пользователя, чтобы ввести число, второе для вычисления, а третье - для печати суммы.

В этом случае у вас есть:

  1. Состояние1 - Подождите, пока пользователь введет число
  2. Состояние2 - Распечатайте сумму
  3. state3 - Вычислить сумму

. Если посмотреть на состояния, вы хотите, чтобы порядок возбуждения начинался с состояния 1, затем состояние 3 и, наконец, состояние2. В противном случае мы будем печатать только пользовательские данные без вычисления суммы. Чтобы еще раз прояснить это, мы ожидаем, что пользователь введет значение, затем вычислит сумму и распечатает сумму.

Вот пример кода:

while(1){
    switch(state){
      case state1:
        // Wait for user input code
        state = state3; // Jump to state3
        break;
      case state2:
        //Print the sum code
        state = state3; // Jump to state3;
      case state3:
        // Calculate the sum code
        state = wait; // Jump to state1
        break;
    }
}

Если мы не используем break, он будет выполняться в этом порядке, state1, state2 и state3. Но используя break, мы избегаем этого сценария и можем упорядочить в правильной процедуре, которая должна начинаться с состояния1, а затем state3 и, наконец, не в состоянии state2.

0
ответ дан Flimzy 28 August 2018 в 18:45
поделиться

Таким образом, вам не нужно повторять код, если вам нужно несколько случаев сделать то же самое:

case THIS:
case THAT:
{
    code;
    break;
}

Или вы можете делать такие вещи, как:

case THIS:
{
   do this;
}
case THAT:
{
   do that;
}

In каскадная мода.

На самом деле ошибка / путаница, если вы спросите меня.

4
ответ дан Francisco Soto 28 August 2018 в 18:45
поделиться

Точно, потому что с некоторым умным размещением вы можете выполнять блоки в каскаде.

-1
ответ дан Hellektor 28 August 2018 в 18:45
поделиться

Я думаю, что это ошибка. В качестве языковой конструкции так же легко иметь break как значение по умолчанию и вместо этого имеет ключевое слово fallthrough. Большая часть кода, который я написал и прочитал, имеет прерывание после каждого случая.

10
ответ дан James K Polk 28 August 2018 в 18:45
поделиться

Java является производным от C, чье наследие включает в себя метод, известный как Duff's Device . Это оптимизация, которая опирается на тот факт, что контроль проваливается от одного случая к другому, в отсутствие оператора break;. К тому времени, когда C был стандартизирован, было много такого кода, как «в дикой природе», и было бы контрпродуктивно менять язык, чтобы разрушить такие конструкции.

3
ответ дан Jim Lewis 28 August 2018 в 18:45
поделиться

Вы можете легко отделить другой тип числа, месяца, счета. Это лучше, если в этом случае

public static void spanishNumbers(String span){

    span = span.toLowerCase().replace(" ", "");
    switch (span){
     case "1":    
     case "jan":  System.out.println("uno"); break;    
     case "2":      
     case "feb":  System.out.println("dos"); break;    
     case "3":     
     case "mar":  System.out.println("tres"); break;   
     case "4":   
     case "apr":  System.out.println("cuatro"); break;
     case "5":    
     case "may":  System.out.println("cinco"); break;
     case "6":     
     case "jun":  System.out.println("seis"); break;
     case "7":    
     case "jul":  System.out.println("seite"); break;
     case "8":    
     case "aug":  System.out.println("ocho"); break;
     case "9":   
     case "sep":  System.out.println("nueve"); break;
     case "10":    
     case "oct": System.out.println("diez"); break;
     }
 }
0
ответ дан John Dev 28 August 2018 в 18:45
поделиться

, потому что есть ситуации, когда вы хотите протекать через первый блок, например, чтобы избежать написания одного и того же кода в нескольких блоках, но все же сможете разделить их на управление mroe. Есть и множество других причин.

0
ответ дан Jonas B 28 August 2018 в 18:45
поделиться

Что касается исторической записи, Тони Хоар изобрел деловое заявление в 1960-х годах во время «структурированного программирования». Оператор дела Тони поддерживал несколько ярлыков в каждом случае и автоматический выход без вопиющих break операторов. Требование для явного break было чем-то, что вышло из линии BCPL / B / C. Деннис Ритчи пишет (в ACM HOPL-II):

Например, конец, который выходит из оператора коммутатора BCPL, не присутствовал на этом языке, когда мы узнали его в 1960-х годах, и поэтому перегрузка ключевого слова break для выхода из оператора B и C должна быть связана с расходящейся эволюцией, а не с сознательными изменениями.

Я не смог найти никаких исторических трудов о BCPL, но Ritchie's комментарий предполагает, что break был более или менее исторической катастрофой. BCPL позже исправил проблему, но, возможно, Ритчи и Томпсон были слишком заняты изобретением Unix, чтобы беспокоиться о такой детали: -)

3
ответ дан Norman Ramsey 28 August 2018 в 18:45
поделиться

Java приходит из C, и это синтаксис из C.

Бывают случаи, когда несколько операторов case имеют только один путь выполнения. Ниже приведен пример, который расскажет вам, сколько дней в месяц.

class SwitchDemo2 {
    public static void main(String[] args) {

        int month = 2;
        int year = 2000;
        int numDays = 0;

        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                numDays = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                numDays = 30;
                break;
            case 2:
                if ( ((year % 4 == 0) && !(year % 100 == 0))
                     || (year % 400 == 0) )
                    numDays = 29;
                else
                    numDays = 28;
                break;
            default:
                System.out.println("Invalid month.");
                break;
        }
        System.out.println("Number of Days = " + numDays);
    }
}
25
ответ дан Romain Hippeau 28 August 2018 в 18:45
поделиться

Не имея автоматического прерывания, добавленного компилятором, позволяет использовать переключатель / case для проверки условий, подобных 1 <= a <= 3, удалив оператор break из 1 и 2.

switch(a) {
  case 1: //I'm between 1 and 3
  case 2: //I'm between 1 and 3
  case 3: //I'm between 1 and 3
          break;
}
0
ответ дан Soufiane Hassou 28 August 2018 в 18:45
поделиться

Как говорили люди раньше, нужно разрешить провал, и это не ошибка, это особенность. Если слишком много break операторов раздражают вас, вы можете легко избавиться от них, используя вместо этого инструкции return. Это на самом деле хорошая практика, потому что ваши методы должны быть как можно меньше (для удобства чтения и ремонтопригодности), поэтому оператор switch уже достаточно велик для метода, следовательно, хороший метод не должен содержать ничего другого , это пример:

public class SwitchTester{
    private static final Log log = LogFactory.getLog(SwitchTester.class);
    public static void main(String[] args){
        log.info(monthsOfTheSeason(Season.WINTER));
        log.info(monthsOfTheSeason(Season.SPRING));
        log.info(monthsOfTheSeason(Season.SUMMER));
        log.info(monthsOfTheSeason(Season.AUTUMN));
    }

    enum Season{WINTER, SPRING, SUMMER, AUTUMN};

    static String monthsOfTheSeason(Season season){
        switch(season){
            case WINTER:
                return "Dec, Jan, Feb";
            case SPRING:
                return "Mar, Apr, May";
            case SUMMER:
                return "Jun, Jul, Aug";
            case AUTUMN:
                return "Sep, Oct, Nov";
            default:
                //actually a NullPointerException will be thrown before reaching this
                throw new IllegalArgumentException("Season must not be null");
        }        
    }
}   

Выполнение печатает:

12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov

, как ожидалось.

0
ответ дан Víctor Gil 28 August 2018 в 18:45
поделиться

Это старый вопрос, но на самом деле я столкнулся с этим случаем без заявления о нарушении сегодня. Не использовать перерыв на самом деле очень полезно, когда вам нужно комбинировать различные функции в последовательности.

, например. используя http-коды ответа для аутентификации пользователя с маркером времени

код ответа сервера 401 - токен устарел -> регенерировать токен и входить в систему пользователя. код ответа сервера 200 - токен в порядке -> войти в систему пользователя.

в операторах case:

case 404:
case 500:
        {
            Log.v("Server responses","Unable to respond due to server error");
            break;
        }
        case 401:
        {
             //regenerate token
        }
        case 200:
        {
            // log in user
            break;
        }

Используя это, вам не нужно вызывать функцию входа в систему для ответа 401, потому что когда токен регенерируется, среда выполнения переходит в регистр 200.

0
ответ дан Vladimír Gašpar 28 August 2018 в 18:45
поделиться

Вы можете делать всевозможные интересные вещи с провалом case.

Например, скажем, вы хотите сделать конкретное действие для всех случаев, но в определенном случае вы хотите сделать это действие плюс что-то другое. Использование оператора switch с провалом сделало бы его довольно простым.

switch (someValue)
{
    case extendedActionValue:
        // do extended action here, falls through to normal action
    case normalActionValue:
    case otherNormalActionValue:
        // do normal action here
        break;
}

Конечно, в конце случая легко забыть оператор break и вызвать неожиданное поведение. Хорошие компиляторы будут предупреждать вас, когда вы опускаете оператор break.

12
ответ дан Zach Johnson 28 August 2018 в 18:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: