Это известная ошибка в Apache 2.4 . Я использовал обходной путь, представленный здесь , и он работает сейчас.
Подводя итог моему первоначальному сообщению и комментариям - есть несколько преимуществ оператора switch
перед оператором if
/ else
:
Более чистый код. Код с несколькими цепочками if
/ иначе if ...
выглядит неаккуратно и сложно обслуживать - переключатель
дает более чистую структуру.
Производительность. Для плотного случая
значений компилятор генерирует таблицу переходов, для разреженного - двоичного поиска или серии if
/ else
, поэтому в худшем случае переключает
работает так же быстро, как if
/ else
, но обычно быстрее. Хотя некоторые компиляторы могут аналогичным образом оптимизировать if
/ else
.
Порядок проверки не имеет значения. Чтобы ускорить серию тестов if
/ else
, нужно сначала поставить более вероятные случаи. С переключателем
/ case
программисту не нужно об этом думать.
По умолчанию может быть где угодно. С if
/ else
регистр по умолчанию должен быть в самом конце - после последнего else
. В переключатель
- по умолчанию
может быть где угодно, где программист сочтет это более подходящим.
Общий код. Если вам нужно выполнить общий код для нескольких случаев, вы можете опустить break
, и выполнение будет "проваливаться" - чего вы не можете достичь с помощью if
/ else
.
Я уверен, что они компилируются с теми же функциями, что и if
/ иначе if
, но я обнаружил переключатель
/ ] case
легче читать, когда их больше 2 или 3 else
s.
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.
Операторы переключения можно оптимизировать по скорости, но они могут занимать больше памяти, если значения case распределены по большому количеству значений.
if / else обычно медленные, так как каждое значение необходимо проверять.
На самом деле оператор switch подразумевает, что вы работаете над чем-то более или менее перечисляемым что дает вам мгновенное представление о том, что происходит.
Тем не менее, включение перечисления на любом объектно-ориентированном языке, вероятно, можно было бы закодировать лучше - и серия if / else для одного и того же значения стиля "enum" будет на по крайней мере так же плохо и даже хуже в передаче смысла.
Переключатель / регистр обычно оптимизируется более эффективно, чем if / else if / else, но иногда ( в зависимости от языка и компилятора) переводится в простые операторы if / else if / else.
Я лично считаю, что операторы switch делают код более читабельным, чем связка операторов if; при условии соблюдения нескольких простых правил. Правила, которым вы, вероятно, должны следовать даже в ситуациях if / else if / else, но это снова мое мнение.
Эти правила:
Это также может зависеть от вашего языка - например, переключение некоторых языков работает только с числовыми типами, поэтому вам не нужно печатать, когда вы работаете с числовыми значениями, числовыми константами. .. и т.д ...
If (day == DAYOFWEEK_MONDAY) {
//...
}
else if (day == DAYOFWEEK_TUESDAY) {
//...
}
//etc...
Или немного проще для чтения ...
switch (day) {
case DAYOFWEEK_MONDAY :
//...
case DAYOFWEEK_TUESDAY :
//...
//etc...
}
Если случаев много, оператор switch кажется более понятным.
Также хорошо, когда у вас есть несколько значений, для которых вы хотите одинаковое поведение - просто использование нескольких операторов case, которые попадают в одну реализацию, намного легче читать, чем if (this || that || someotherthing | | ...)
Также помните, что операторы 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;
}
, пожалуйста, помните, что case / select обеспечивает дополнительную гибкость: условие
, а также выполняется намного быстрее (с помощью таблицы переходов / поиска) * исторически
Ну, одна из причин - ясность ....
если у вас есть переключатель / футляр, то выражение не может измениться .... 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 одинаковыми?» или «почему они разные»?
Четкость. Как я сказал здесь , ключом к разгадке else if
является
частота, с которой ELSE IF используется гораздо более ограниченно чем разрешено синтаксисом. Это кувалда гибкости, разрешая совершенно не связанные условия для тестирования. Но это обычно используется, чтобы прихлопнуть мух CASE, сравнение того же выражения с альтернативными значениями ...
Это снижает читаемость код. Поскольку конструкция позволяет Вселенная условной сложности, читателю нужно сохранить больше возможности в уме при разборе ELSE IF, чем при синтаксическом анализе CASE.
устраняя озабоченность по поводу того, что все внутри переключателя имеет эквивалентную область видимости, вы всегда можете перенести логику case в другой блок {}, вот так ..
switch( thing ) {
case ONETHING: {
int x; // local to the case!
...
}
break;
case ANOTHERTHING: {
int x; // a different x than the other one
}
break;
}
.. сейчас я не говорю это мило. Просто представьте это как что-то возможное , если вам абсолютно необходимо изолировать что-то в одном случае от другого.
еще одна мысль о проблеме с областью видимости - кажется хорошей практикой ставить только один переключатель внутри функции, и не более того. В этих обстоятельствах область видимости переменных не вызывает особого беспокойства, поскольку в этом случае вы обычно имеете дело только с одним случаем выполнения при любом заданном вызове функции.
Хорошо, последняя мысль о переключателях: если функция содержит более пары переключателей, вероятно, пора провести рефакторинг вашего кода.
case case в основном используется для выбора, который нужно сделать в программировании. Это не связано с условным оператором как:
если ваша программа требует только выбора, то почему вы используете блок if / else и увеличиваете усилия по программированию плюс это снижает скорость выполнения программы.
Основная причина этого - удобство обслуживания и удобочитаемость. Легко сделать код более читаемым и поддерживаемым с помощью оператора Switch / case, а затем if / else. Поскольку у вас много if / else, тогда код становится таким беспорядочным, как nest, и его очень трудно поддерживать.
И еще одна причина - время исполнения.