Оператор переключения с возвратами — кодирует правильность

Скажем, у меня есть код в C приблизительно с этой структурой:

switch (something)
{
    case 0:
      return "blah";
      break;

    case 1:
    case 4:
      return "foo";
      break;

    case 2:
    case 3:
      return "bar";
      break;

    default:
      return "foobar";
      break;
}

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

Что Вы думаете? Прекрасен это для удаления их? Или Вы сохранили бы их для увеличенной "правильности"?

82
задан Jonas Stein 20 November 2019 в 22:05
поделиться

14 ответов

Удалите утверждения break. Они не нужны и, возможно, некоторые компиляторы будут выдавать предупреждения "Unreachable code".

122
ответ дан 24 November 2019 в 09:09
поделиться

Лично я склонен терять перерыв с. Возможно, одним из источников этой привычки является программирование оконных процедур для приложений Windows:

LRESULT WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_SIZE:
            return sizeHandler (...);
        case WM_DESTROY:
            return destroyHandler (...);
        ...
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Я лично считаю этот подход намного более простым, лаконичным и гибким, чем объявление возвращаемой переменной, установленной каждым обработчиком, с последующим ее возвратом в конце. При таком подходе break являются избыточными и поэтому должны исчезнуть - они не служат никакой полезной цели (синтаксически или визуально IMO) и только раздувают код.

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

Я бы сказал удалить их и определить ветвь по умолчанию: branch.

2
ответ дан 24 November 2019 в 09:09
поделиться

Как вы думаете? Их можно удалить? Или вы бы оставили их для большей «правильности»?

Их можно удалить. Использование return - это в точности сценарий, в котором не следует использовать break .

2
ответ дан 24 November 2019 в 09:09
поделиться

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

2
ответ дан 24 November 2019 в 09:09
поделиться

Удалите их. Возвращаться из операторов case идиоматично, иначе это шум "недостижимого кода".

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

Я говорю, удалите их. Если ваш код настолько нечитабелен, что вам нужно втыкать в него разрывы «на всякий случай», вам следует пересмотреть свой стиль кодирования :)

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

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

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

Я знаю, что это не так, когда есть return вместо break , но так мои глаза «читают» блоки case в переключателе, поэтому я лично предпочел бы, чтобы каждый случай сочетался с разрывом . Но многие компиляторы жалуются на то, что разрыв после return является избыточным / недостижимым, и, по-видимому, я все равно в меньшинстве.

Избавьтесь от разрыва после возврата .

NB: все это игнорирует, является ли нарушение правила единого входа / выхода хорошей идеей или нет. Что касается этого, у меня есть мнение, которое, к сожалению, меняется в зависимости от обстоятельств ...

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

Я бы обычно писал код без них. ИМО, мертвый код, как правило, указывает на небрежность и/или отсутствие понимания.

Конечно, я бы также рассмотрел что-то вроде:

char const *rets[] = {"blah", "foo", "bar"};

return rets[something];

Edit: even with the edited post, this general idea can work fine:

char const *rets[] = { "blah", "foo", "bar", "bar", "foo"};

if ((unsigned)something < 5)
    return rets[something]
return "foobar";

В какой-то момент, особенно если входные значения разрежены (например, 1, 100, 1000 и 10000), вам понадобится разреженный массив. Вы можете реализовать это в виде дерева или карты (хотя, конечно, переключатель также работает в этом случае).

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

Я бы удалил их. По моему мнению, такой мертвый код должен считаться ошибкой, потому что он заставляет вас сделать двойной дубль и спросить себя "Как бы я вообще выполнил эту строку?"

.
5
ответ дан 24 November 2019 в 09:09
поделиться

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

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

6
ответ дан 24 November 2019 в 09:09
поделиться

Лично я бы убрал возвраты, а перерывы оставил себе. Я бы использовал оператор switch для присвоения значения переменной. Затем верните эту переменную после оператора switch.

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

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

8
ответ дан 24 November 2019 в 09:09
поделиться

Я бы пошел другим путем. Не делайте RETURN в середине метода/функции. Вместо этого просто поместите возвращаемое значение в локальную переменную и отправьте его в конце.

Лично я нахожу следующий вариант более читабельным:

String result = "";

switch (something) {
case 0:
  result = "blah";
  break;
case 1:
  result = "foo";
  break;
}

return result;
30
ответ дан 24 November 2019 в 09:09
поделиться

Не лучше ли иметь массив с

arr[0] = "blah"
arr[1] = "foo"
arr[2] = "bar"

и сделать return arr[something];?

Если речь идет о практике в целом, то вам следует сохранить операторы break в switch. В случае, если в будущем вам не понадобятся операторы return, это уменьшает вероятность того, что он перейдет в следующий case.

2
ответ дан 24 November 2019 в 09:09
поделиться
Другие вопросы по тегам:

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