Часто, когда я слышу об операторе switch, его откладывают как способ заменить длинные цепочки if ... else. Но, похоже, что когда я использую оператор switch, я пишу больше кода, который я бы просто написал, если ... еще. У вас также есть другие проблемы, такие как хранение всех переменных для всех вызовов в одной области .
Вот некоторый код, который представляет поток, который я обычно пишу ( благодаря diam )
String comment; // The generated insult.
int which = (int)(Math.random() * 3); // Result is 0, 1, or 2.
if (which == 0) {
comment = "You look so much better than usual.";
} else if (which == 1) {
comment = "Your work is up to its usual standards.";
} else if (which == 2) {
comment = "You're quite competent for so little experience.";
} else {
comment = "Oops -- something is wrong with this code.";
}
Затем они хотят, чтобы я заменил это на это:
String comment; // The generated insult.
int which = (int)(Math.random() * 3); // Result is 0, 1, or 2.
switch (which) {
case 0:
comment = "You look so much better than usual.";
break;
case 1:
comment = "Your work is up to its usual standards.";
break;
case 2:
comment = "You're quite competent for so little experience.";
break;
default:
comment = "Oops -- something is wrong with this code.";
}
Похоже, гораздо больше кода в гораздо более неудобном синтаксисе. Но есть ли преимущество в использовании оператора switch?
Ответы:
Для этой конкретной ситуации мне кажется, что и то,
if
и другоеcase
- плохой выбор. Я бы использовал простой массив:В качестве примечания следует обычно вычислять множитель на основе размера массива, а не жестко кодировать его
3
.Что касается , когда вы бы использовать случай / выключатель, отличие от каскада
if
утверждений (или , по меньшей мере , одно существенное различие) является то , чтоswitch
может полуавтоматически оптимизировать в зависимости от количества и плотности значений, в то время как каскадif
заявлений листьев компилятор без особого выбора, кроме как генерировать код в том виде, в каком вы его написали, тестируя одно значение за другим, пока не найдете совпадение. Только с тремя реальными случаями это вряд ли вызывает беспокойство, но при достаточном количестве это может / может быть значительным.источник
case
заявлением или каскадif
заявлений подходящих. В большинстве случаев они (посредственные) заменители какого-то типа карт / массивов, и вам лучше использовать один из последних напрямую.static const
массив, чтобы он всегда существовал (но в вопросе не было дано ни одного языка, поэтому я старался не использовать ни одного в ответе). ).Проблема с
if...else if...
цепочкой заключается в том, что когда я прихожу, чтобы прочитать ее, я должен посмотреть на каждоеif
условие, чтобы понять, что делает программа. Например, у вас может быть что-то вроде этого:(очевидно, для такого количества утверждений это не так уж плохо)
У меня не было бы никакой возможности узнать, что вы изменили переменную условия на полпути, не читая каждое утверждение. Однако, поскольку
switch
вы ограничены только одной переменной условия, я могу сразу увидеть, что происходит.В конце концов, однако, я бы предпочел ни один
switch
или цепьif...else if
. Часто лучшим решением является какая-то таблица переходов или словарь для случаев, как в исходном вопросе, или полиморфизм (если ваш язык поддерживает это). Конечно, это не всегда возможно, ноswitch
в качестве первого шага я бы искал решение, которое избегает ...источник
Приведенный выше способ написания этого типа случая переключения довольно распространен. Причина, по которой вы почувствовали регистр переключателя, если он более объемный, заключается в том, что ваше тело было только одной строкой, а в случае переключателя вам также потребовалось выражение break. Таким образом, корпус переключателя имел вдвое больший размер, чем корпус. При более содержательном коде оператор break не сильно прибавит к телу. Для однострочного тела обычной практикой является написание кода в той же строке, что и оператор case.
Как уже упоминали другие, случай переключения делает намерение более ясным, вы хотите принять решение на основе значения одной переменной / выражения. Мои комментарии сделаны исключительно с точки зрения читабельности и не основаны на производительности.
источник
return
соответствующая строка, вы можете исключитьbreak
операторы.В этом случае оператор switch более четко соответствует назначению кода: выберите действие, которое нужно выполнить, основываясь на одном значении.
С другой стороны, утверждения if гораздо сложнее читать - вы должны посмотреть на все из них, чтобы быть уверенным в том, что происходит. Для меня это меньше кода (даже если количество символов может быть немного выше), так как меньше умственного анализа.
источник
Я согласен с Джерри, что для этого конкретного случая лучше использовать массив строк, но в целом лучше использовать оператор switch / case, чем цепочку elseifs. Его легче читать, и иногда компилятор лучше справляется с оптимизацией, но есть и другое преимущество: его намного проще отлаживать.
Когда вы нажмете на этот переключатель, вам нужно будет только один раз перейти в нужную ветку, вместо того, чтобы осторожно перешагнуть через несколько операторов if по одному, и, возможно, слишком быстро нажать клавишу и пройти мимо нее, пропустить что-то и начать все сначала.
источник
Я предпочитаю switch в таких случаях, он намного лучше соответствует точке кода, выполняет разные операторы для каждого другого входного значения.
if..else
Действует больше как «трюк» , чтобы добиться того же эффекта.switch
Заявления также чище, опечатку легко спрятать во всех этих==
Кроме того, для больших блоков в C, переключение происходит быстрее.
else..if
может быть более уместным, когда у вас есть что-то вроде диапазонов (между 1 и 100, делайте это, между 100 и 200, делайте это) или в C, когда вы пытаетесь переключаться с такими элементами, как строки (это возможно в других языках). Что то же самое.Я склонен использовать много переключателей, когда я программирую на C.
источник
Выберите что-то, что является эффективным, кратким, и затем документируйте не только то, что вы сделали, но и почему.
Код может быть пересмотрен, и не всегда его первоначальным автором.
Есть моменты, когда вы можете сознательно выбрать одну реализацию, а не другую, потому что вы думаете о коде, который не существует.
источник
Мне вообще не нравится ни один подход. Длинное переключение или если операторы просто начинают подвергаться рефакторингу в объектно-ориентированную абстракцию (однако ваш пример я бы классифицировал как короткий, а не длинный).
Я бы лично обернул такой код в отдельный вспомогательный метод.
Размещение переключателя в отдельном методе позволяет размещать операторы return непосредственно внутри оператора switch (по крайней мере, в c #), что также устраняет необходимость в операторах break, делая код намного проще для чтения.
И это намного лучше, чем подход if / else if / else if.
источник
В python нет оператора switch, потому что если / elif / else это хорошо:
Просто верно?
источник
Elif
это просто оператор if с несколькими пропущенными буквами. Это определенно больше похоже наif
утверждение, чем на утверждение переключателя. Тот факт, что Питон НЕ имеет переключателя, заставляет того, кто ненавидит их (таких как я), думать, что они не одиноки.meta
если это не известная тема. Спасибо, что дали мне свидетеля.Одна из вещей, которая делает стиль C / C #
switch
особенно раздражающей, это настойчивое требование, чтобыcase
значение было литералом. Одна хорошая вещь в VB / VB.NET - это то, чтоselect/case
каждый случай может быть любым логическим выражением. Это удобно Поскольку ряд взаимоисключающих логических выражений часто бывает полезен, серия if / else if более гибкая, не говоря уже о том, что она более эффективна для ввода и чтения.источник