Оператор переключения Fallthrough … это должен быть позволен? [закрытый]

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

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

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

109
задан davidkonrad 6 March 2014 в 13:57
поделиться

11 ответов

Это может зависеть от того, что Вы рассматриваете fallthrough. Я соглашаюсь с этим видом вещи:

switch (value)
{
  case 0:
    result = ZERO_DIGIT;
    break;

  case 1:
  case 3:
  case 5:
  case 7:
  case 9:
     result = ODD_DIGIT;
     break;

  case 2:
  case 4:
  case 6:
  case 8:
     result = EVEN_DIGIT;
     break;
}

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

И обратите внимание на то, что я использую определение FAQ C++ "зло"

82
ответ дан Fred Larson 24 November 2019 в 03:22
поделиться

Это - обоюдоострый меч. Иногда очень полезный, часто опасный.

, Когда это хорошо? Когда Вы хотите 10 случаев, все обработали тот же путь...

switch (c) {
  case 1:
  case 2:
            ... do some of the work ...
            /* FALLTHROUGH */
  case 17:
            ... do something ...
            break;
  case 5:
  case 43:
            ... do something else ...
            break;
}

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

51
ответ дан Adam Bellaire 24 November 2019 в 03:22
поделиться

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

switch ($someoption) {
  case 'a':
  case 'b':
  case 'c':
    // do something
    break;
  case 'd':
  case 'e':
    // do something else
    break;
}

Предполагают делать это с если/еще. Это была бы путаница.

20
ответ дан Lucas Oman 24 November 2019 в 03:22
поделиться

Вы услышали о устройство Вареного пудинга ? Это - яркий пример использования переключателя fallthrough.

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

20
ответ дан tzot 24 November 2019 в 03:22
поделиться

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

пример, для обновления старых версий некоторых данных:

switch (version) {
    case 1:
        // update some stuff
    case 2:
        // update more stuff
    case 3:
        // update even more stuff
    case 4:
        // and so on
}
10
ответ дан 24 November 2019 в 03:22
поделиться

Я любил бы другой синтаксис в нейтрализации в переключателях, чем-то как, errr..

switch(myParam)
{
  case 0 or 1 or 2:
    // do something;
    break;
  case 3 or 4:
    // do something else;
    break;
}

Примечание: Это уже было бы возможно с перечислениями, если Вы объявляете все случаи на своем праве флагов использования перечисления? Не звучит настолько плохим также, случаи могли (должен?) очень хорошо уже быть частью Вашего перечисления.

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

int value = 10;
value.Switch()
  .Case(() => { /* do something; */ }, new {0, 1, 2})
  .Case(() => { /* do something else */ } new {3, 4})
  .Default(() => { /* do the default case; */ });

, Хотя это, вероятно, даже менее читаемо :P

6
ответ дан Erik van Brakel 24 November 2019 в 03:22
поделиться

Как с чем-либо: если используется с осторожностью, это может быть изящный инструмент.

Однако я думаю недостатки больше, чем выравнивают по ширине, чтобы НЕ использовать его, и наконец еще не позволять его (C#). Среди проблем:

  • легко "забыть" повреждение
  • , не всегда очевидно для специалистов по обслуживанию кода, ЧТО опущенное повреждение было намеренное

хорошее использование переключателя/случая fallthrough:

switch (x)
{
case 1:
case 2:
case 3:
 do something
 break;
}

использование BAAAAAD переключателя/случая fallthrough:

switch (x)
{
case 1:
    some code
case 2:
    some more code
case 3:
    even more code
    break;
}

Это может быть переписано с помощью если/еще конструкции без потери вообще, по-моему.

Мое заключительное слово: держитесь подальше проваливаются маркировки случая как в ПЛОХОМ примере, если Вы не поддерживаете унаследованный код, где этот стиль используется и хорошо понимается.

5
ответ дан steffenj 24 November 2019 в 03:22
поделиться

Мощный и опасный. Самая большая проблема с проваливается, то, что это не явно. Например, если Вы сталкиваетесь с часто отредактированным кодом, который имеет переключатель с падением-throughs, как Вы знаете, что это является намеренным и не ошибка?

Где угодно я использую его, я удостоверяюсь, что это правильно прокомментировано:

switch($var) {
    case 'first':
        // fall-through
    case 'second':
        i++;
        break;
 }
4
ответ дан Dan Hulton 24 November 2019 в 03:22
поделиться

Мне не нравится, когда мой switch операторы проваливается - это слишком подвержено ошибкам и твердо читать. Единственное исключение - когда [приблизительно 111] операторы все делают точно то же самое.

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

2
ответ дан Matt Dillard 24 November 2019 в 03:22
поделиться

В некоторых случаях использование падения-throughs является действием лени со стороны программиста - они могли использовать серию || операторы, например, но вместо этого использовать серию 'всеобъемлющих' случаев переключателя.

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

Это - вероятно, вопрос стиля и как программисты думают, но я не вообще люблю удаление компонентов языка от имени 'безопасности' - который является, почему я ухаживаю к C и его вариантам/потомкам за больше, чем, скажем, Java. Мне нравится способность обезьяне - вокруг с указателями и т.п., даже когда у меня нет "причины" для.

1
ответ дан warren 24 November 2019 в 03:22
поделиться

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

1
ответ дан BCS 24 November 2019 в 03:22
поделиться
Другие вопросы по тегам:

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