Почему Переключатель/Случай и не, Если/Еще, Если?

Это известная ошибка в Apache 2.4 . Я использовал обходной путь, представленный здесь , и он работает сейчас.

60
задан a3f 18 April 2015 в 16:35
поделиться

15 ответов

Подводя итог моему первоначальному сообщению и комментариям - есть несколько преимуществ оператора switch перед оператором if / else :

  1. Более чистый код. Код с несколькими цепочками if / иначе if ... выглядит неаккуратно и сложно обслуживать - переключатель дает более чистую структуру.

  2. Производительность. Для плотного случая значений компилятор генерирует таблицу переходов, для разреженного - двоичного поиска или серии if / else , поэтому в худшем случае переключает работает так же быстро, как if / else , но обычно быстрее. Хотя некоторые компиляторы могут аналогичным образом оптимизировать if / else .

  3. Порядок проверки не имеет значения. Чтобы ускорить серию тестов if / else , нужно сначала поставить более вероятные случаи. С переключателем / case программисту не нужно об этом думать.

  4. По умолчанию может быть где угодно. С if / else регистр по умолчанию должен быть в самом конце - после последнего else . В переключатель - по умолчанию может быть где угодно, где программист сочтет это более подходящим.

  5. Общий код. Если вам нужно выполнить общий код для нескольких случаев, вы можете опустить break , и выполнение будет "проваливаться" - чего вы не можете достичь с помощью if / else .

160
ответ дан 24 November 2019 в 17:26
поделиться

Я уверен, что они компилируются с теми же функциями, что и if / иначе if , но я обнаружил переключатель / ] case легче читать, когда их больше 2 или 3 else s.

0
ответ дан 24 November 2019 в 17:26
поделиться

Smalltalker может отклонить как switch, так и if-then-else, и может написать что-то вроде: -

shortToLongDaysMap := Dictionary new.

shortToLongDaysMap
at: 'Mon'     put:  'Monday';
at: 'Tue'     put:  'Tuesday';
at: 'Wed'     put:  'Wednesday'
etc etc.

longForm := shortToLongDaysMap at: shortForm ifAbsent: [shortForm]

Это тривиальный пример, но я надеюсь, вы видите, как этот метод масштабируется для больших чисел случаев.

Обратите внимание на второй аргумент в: IfAbsent: аналогичен предложению по умолчанию для оператора case.

0
ответ дан 24 November 2019 в 17:26
поделиться

Операторы переключения можно оптимизировать по скорости, но они могут занимать больше памяти, если значения case распределены по большому количеству значений.

if / else обычно медленные, так как каждое значение необходимо проверять.

0
ответ дан 24 November 2019 в 17:26
поделиться

На самом деле оператор switch подразумевает, что вы работаете над чем-то более или менее перечисляемым что дает вам мгновенное представление о том, что происходит.

Тем не менее, включение перечисления на любом объектно-ориентированном языке, вероятно, можно было бы закодировать лучше - и серия if / else для одного и того же значения стиля "enum" будет на по крайней мере так же плохо и даже хуже в передаче смысла.

4
ответ дан 24 November 2019 в 17:26
поделиться

Переключатель / регистр обычно оптимизируется более эффективно, чем if / else if / else, но иногда ( в зависимости от языка и компилятора) переводится в простые операторы if / else if / else.

Я лично считаю, что операторы switch делают код более читабельным, чем связка операторов if; при условии соблюдения нескольких простых правил. Правила, которым вы, вероятно, должны следовать даже в ситуациях if / else if / else, но это снова мое мнение.

Эти правила:

  • Никогда и никогда не используйте более одной линии на вашем блоке переключения. Вызовите метод или функцию и выполняйте там свою работу.
  • Всегда проверяйте наличие разрыва / пропадания случая.
  • Пузыри исключения.
4
ответ дан 24 November 2019 в 17:26
поделиться

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

If (day == DAYOFWEEK_MONDAY) {
    //...
}
else if (day == DAYOFWEEK_TUESDAY) {
    //...
}
//etc...

Или немного проще для чтения ...

switch (day) {
    case DAYOFWEEK_MONDAY :
        //...
    case DAYOFWEEK_TUESDAY :
        //...
    //etc...
}
6
ответ дан 24 November 2019 в 17:26
поделиться

Если случаев много, оператор switch кажется более понятным.

Также хорошо, когда у вас есть несколько значений, для которых вы хотите одинаковое поведение - просто использование нескольких операторов case, которые попадают в одну реализацию, намного легче читать, чем if (this || that || someotherthing | | ...)

9
ответ дан 24 November 2019 в 17:26
поделиться

Также помните, что операторы switch позволяют продолжить поток управления, что позволяет вам красиво комбинировать условия, позволяя вам добавлять дополнительный код для определенных условий, например, в следующем фрагменте кода:

switch (dayOfWeek)
{
    case MONDAY:
        garfieldUnhappy = true;
    case TUESDAY:
    case WEDNESDAY:
    case THURSDAY:
    case FRIDAY:
       weekDay = true;
       break;
    case SATURDAY:
       weekendJustStarted = true;
    case SUNDAY:
       weekendDay = true;
       break;
}

Использование здесь операторов if / else было бы не лучшим вариантом.

if (dayOfWeek == MONDAY)
{
    garfieldUnhappy = true;
}
if (dayOfWeek == SATURDAY)
{
    weekendJustStarted = true;
}
if (dayOfWeek == MONDAY || dayOfWeek == TUESDAY || dayOfWeek == WEDNESDAY
    || dayOfWeek == THURSDAY || dayOfWeek == FRIDAY)
{
    weekDay = true;
}
else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY)
{
    weekendDay = true;
}
11
ответ дан 24 November 2019 в 17:26
поделиться

, пожалуйста, помните, что case / select обеспечивает дополнительную гибкость: условие

  • оценивается, когда
  • становится достаточно гибким, чтобы создавать такие вещи, как устройство Даффа
  • провал (также известный как case без перерыва)

, а также выполняется намного быстрее (с помощью таблицы переходов / поиска) * исторически

16
ответ дан 24 November 2019 в 17:26
поделиться

Ну, одна из причин - ясность ....

если у вас есть переключатель / футляр, то выражение не может измениться .... ie

switch (foo[bar][baz]) {
case 'a':
    ...
    break;
case 'b': 
    ...
    break;
}

тогда как с if / else, если вы напишете по ошибке (или намеренно):

if (foo[bar][baz] == 'a') {
    ....
}
else if (foo[bar][baz+1] == 'b') {
    ....
}

люди, читающие ваш код, зададутся вопросом «были ли выражения foo одинаковыми?» или «почему они разные»?

31
ответ дан 24 November 2019 в 17:26
поделиться

Четкость. Как я сказал здесь , ключом к разгадке else if является

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

Это снижает читаемость код. Поскольку конструкция позволяет Вселенная условной сложности, читателю нужно сохранить больше возможности в уме при разборе ELSE IF, чем при синтаксическом анализе CASE.

4
ответ дан 24 November 2019 в 17:26
поделиться

устраняя озабоченность по поводу того, что все внутри переключателя имеет эквивалентную область видимости, вы всегда можете перенести логику case в другой блок {}, вот так ..

switch( thing ) {
    case ONETHING: {
        int x; // local to the case!
        ...
        }
        break;
    case ANOTHERTHING: {
        int x; // a different x than the other one
        }
        break;
}

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

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

Хорошо, последняя мысль о переключателях: если функция содержит более пары переключателей, вероятно, пора провести рефакторинг вашего кода.

3
ответ дан 24 November 2019 в 17:26
поделиться

case case в основном используется для выбора, который нужно сделать в программировании. Это не связано с условным оператором как:

если ваша программа требует только выбора, то почему вы используете блок if / else и увеличиваете усилия по программированию плюс это снижает скорость выполнения программы.

1
ответ дан 24 November 2019 в 17:26
поделиться

Основная причина этого - удобство обслуживания и удобочитаемость. Легко сделать код более читаемым и поддерживаемым с помощью оператора Switch / case, а затем if / else. Поскольку у вас много if / else, тогда код становится таким беспорядочным, как nest, и его очень трудно поддерживать.

И еще одна причина - время исполнения.

0
ответ дан 24 November 2019 в 17:26
поделиться