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


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.