С точки зрения обслуживания, считается ли «еще какое-то время» без промежуточных скобок безопасным?


26

Есть else whileбез промежуточных брекеты считаются «безопасными» обслуживание мудрым?

Написание if-elseкода без скобок, как показано ниже ...

if (blah)
    foo();
else
    bar();

... несет в себе риск, потому что отсутствие фигурных скобок делает очень легким непреднамеренное изменение значения кода.

Тем не менее, ниже также рискованно?

if (blah)
{
    ...
}
else while (!bloop())
{
    bar();
}

Или else whileбез промежуточных скобок считается "безопасным"?


20
для меня else whileвыглядит неприглядно. Я бы использовал else { while (condition) { ... } }.
— Иоахим Зауэр

7
Я думаю, что это слишком субъективно для правильного ответа ... Я сам не стал бы этого делать, потому что не ожидал, что цикл там, и думает, что не ожидаю, что затруднит чтение.
— Иоганнес

7
Я хотел бы извлечь метод для while-вещи
— комнат

12
Честно говоря, это дает мне мурашки по коже. ifоценивается только один раз, но whileобозначает цикл, поэтому соединение обоих дает мне необоснованное ощущение, что ifэто часть цикла ... каким-то образом ...
— user281377 20.12.12

4
А что, если в elseпредложении вы хотите сделать while и сделать что-то еще? Просто используйте брекеты, пожалуйста.
— Карлос Кампдеррос

Ответы:


57

Это напоминает мне этот код:

if ( ... ) try {
..
} catch (Exception e) {
..
} else {
...
}

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


18
Хороший пример. Какой ужасный способ написать это.
— Лев

4
Вау, этот ответ смехотворно убедителен!
— Мердад

Вы можете легко настроить современные среды IDE для автоматического форматирования кода при сохранении, включая вставку фигурных скобок и исправление отступов. Так что это только половина аргумента. При правильном отступе это не создаст проблем с читабельностью, независимо от того, есть ли скобки или нет.
— Ганс-Петер Стёрр

55

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

Все остальное (без каламбура) оставляет возможность для недопонимания и / или вопросов обслуживания. Это центральный аспект идеи ОП, являющейся «небезопасной».

Я также был бы очень осторожен с тем, чтобы включать в while()одну строку с else- будь то в скобках или нет. Это не читается правильно для меня ... отсутствие каких-либо дополнительных масок отступа, что это elseпункт. А отсутствие ясности приводит к недоразумениям (см. Выше).

Поэтому в этом примере я бы настоятельно советовал / рекомендовал (и настаивал в своей команде):

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

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

-- Редактировать --

В последнее время Apple страдала от уязвимости SSL, вызванной плохим исправлением, которое добавило вторую строку в единую строку без скобок. Итак, давайте уложить идею, что одиночные линии без скобок в порядке?


2
Я согласен с тем, чтобы быть единственным правильным термином, чтобы следовать другому. Если бы это было, else whileя бы, наверное, даже не заметил, что в быстром просмотре кода был цикл, особенно если условие, которое я искал, было удовлетворено условием if.
— Дрейк Кларрис

3
Это забавно. Все говорят, что легче читать, если все в скобках. Я считаю, что все наоборот. Если это всего лишь одно утверждение, то его не использовать в скобках, чтобы его было легче читать. Меньше беспорядка. Это может быть только потому, что я всегда так делал.
— Джефф Дэвис

2
@JeffDavis это хороший улов. «Легче читать» - типичное приглашение к бесполезной священной войне. Я, например, предпочитаю фигурные скобки, но не из-за неуместного «проще читаемого» мусора (для меня, например, с точностью до наоборот), а потому, что его сложнее сломать при дальнейшей поддержке кода. Кстати OP пишется это лучше в их вопрос: это else whileбез вмешательства брекеты считаются «безопасными» ?
— комнат

@JeffDavis - я знаю, что этой теме уже два года, но Apple недавно обнаружила, почему не использовать скобки - не очень хорошая идея andrewbanks.com/…
— Эндрю

@Andrew Кстати, язык Apple Swift теперь явно запрещает управление потоком в одну строку. Эта ошибка может быть одной из причин для этого.
— Sulthan

6

Меня всегда учили держать все в скобках, с отступом и комментариями. Я считаю, что намного легче читать и определять ошибки. Лично я чувствую, что модульность является ключевым фактором, поэтому я всегда писал бы код следующим образом:

    if(blah)
    {
     ....
    }
    else
    {
       while(!bloop()
       {
        bar;
       }
    }

6

Я бы извлек метод и сделал это

if ( blah )
{
    ...
}
else
{
   newMethod();
}

См. Метод «извлечения метода», объясненный на сайте каталога рефакторинга :

У вас есть фрагмент кода, который можно сгруппировать вместе.

Превратите фрагмент в метод, имя которого объясняет назначение метода.

void printOwing() {
    printBanner();

    //print details
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + getOutstanding());
}

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + outstanding);
}

Зависит ... если, например, в цикле while использовались данные уровня функции, теперь вам нужно добавить эти данные на уровень модуля (или класса, если используется C ++). И если только небольшой фрагмент кода, вы в тривиальных методах. Но иногда, в зависимости от обстоятельств, я бы согласился.
— Андрей

1
+1 Компиляторы Smart C ++ могут встроить функцию. В среде .Net небольшие функции лучше благодаря JIT.
— Работа

4

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

Всегда рекомендуется модулировать ваш код. Если вам нужно поместить цикл while в другую часть, поместите его в блок, чтобы другие при работе над вашим кодом могли легко понять логику.

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Хорошей практикой является размещение кода в блоках. Это делает его более простым и легким для понимания и отладки.


4

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

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

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

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


3

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

if (...)
   foo();
else while(...)
   bar();

... Я действительно нахожу это " else while(...)" замечательно читаемым! Это даже читается как обычный английский! Но я думаю, что все найдут это странным, потому что это, по меньшей мере, необычно.

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


3
это будет особенно читаемо после того, как некоторые невинные сопровождающие изменят else while(...) bar();что-то вроде else while(...) foobar(); bar();:)
— gnat

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

2
«Всегда пишите код, как будто человек, который будет поддерживать ваш код, является жестоким психопатом, который знает, где вы живете». ( Alan Braggins )
— комар

1
Ну, все сводится к тому, что вы думаете, самый глупый уровень человека, работающего над вашим кодом будет. Я утверждаю, что если ваш «сопровождающий» запутается в этих четырех строках кода ... тогда у вас возникнет огромная проблема. И если это жестокий псих, у вас есть два. ;)
— dagnelies

1
если - ну, ссылка, на которую я ссылаюсь выше, имеет расширенную версию этой цитаты: Программист 1: «Здесь есть хорошая цитата -« Всегда используйте код, как если бы человек, который будет поддерживать ваш код, является жестоким психопатом, который знает, где вы живете »» , Программист 2: (смотрит на сопровождающего) «Что значит« как будто »?»
— комнат

2

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

if(blah) {
    foo();
}
else {
    bar();
}

Расположение скобок, вероятно, вызывает больше аргументов, чем что-либо, кроме (или, возможно, включая) религию!
— Андрей

Согласовано. Отредактирую мой ответ, чтобы подчеркнуть их существование, а не положение.
— Цветомир Димитров

2

Что такого плохого в брекетах, что так много людей стараются не писать их?

Какую проблему точно else whileрешить?

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

Цитата философии Unix:

Правило Ясности: Ясность лучше, чем ум.

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


1

Там нет ничего плохого в

if (blah)
    foo();
else
    bar();

так же, как нет ничего плохого в

if (blah) foo(); else bar();

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

Но если вы выберете один путь, придерживайтесь его - последовательность - это король. Итак, ваш второй пример очень плохой, так как выражение if имеет скобки для своего оператора, тогда как оператор while должен быть внутри скобок для предложения else, а не за его пределами.


кроме того, я видел этот код раньше:

if (x) foo()
{
  bar();
}

и это было написано самим стандартом кодирования нацистами (который настаивал на скобках для всего).


1

Современные IDE могут быть легко сконфигурированы для переформатирования (включая удаление или добавление ненужных скобок) и / или повторного создания кода при сохранении файла. Таким образом, ваш пример будет выглядеть автоматически, например

if (blah) {
  blub();
} else
  while (!bloop()) {
    bar();
  }

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

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

if (blah) blub();
else while (!bloop()) bar();

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.