Является ли плохой практикой использование оператора if без фигурных скобок? [закрыто]

131

Я видел такой код:

if(statement)
    do this;
else
    do this;

Однако я думаю, что это более читабельно:

if(statement){
    do this;
}else{
    do this;
}

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

jerebear
источник
На мой взгляд, это плохо, потому что вы начинаете полагаться на отступы между пробелами, которые почти никогда не бывают полностью согласованными. Когда читателю приходится беспокоиться о таких вещах, это сбивает с толку ход мысли читателя.
Шридхар Сарнобат

Ответы:

215

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

С точки зрения ремонтопригодности всегда разумнее использовать вторую форму.

РЕДАКТИРОВАТЬ: Нед указывает на это в комментариях, но я думаю, что здесь тоже стоит сделать ссылку. Это не просто гипотетическая чушь про башню из слоновой кости: https://www.imperialviolet.org/2014/02/22/applebug.html

Кли
источник
17
И вы всегда должны кодировать для удобства обслуживания. В конце концов, я почти уверен, что компилятору все равно, какую форму вы используете. Однако ваши коллеги могут быть недовольны, если вы введете ошибку из-за глупой ошибки фигурных скобок.
Эстебан Арая,
12
Или вы можете использовать язык, который не использует скобки для кодовых блоков ...
Тор Валамо,
10
@ lins314159 - Нет, я имею в виду питон. Потому что я шовинист в этом отношении.
Тор Валамо
17
Дополнительные доказательства ошибок могут (и случаются): imperialviolet.org/2014/02/22/applebug.html
Нед,
8
Утверждать, что ошибка SSL является аргументом в пользу фигурных скобок, неискренне. Не то чтобы разработчик намеревался писать, if (…) { goto L; goto L; }но забыл о фигурных скобках. Совершенно случайно, что `` if (…) {goto L; goto L; } `не является ошибкой безопасности, потому что это все еще ошибка (только не с последствиями для безопасности). В другом примере все может пойти в обратном направлении, и код без скобок может оказаться случайно безопасным. В третьем примере код без фигурных скобок изначально не содержал бы ошибок, и разработчик вводил опечатку при добавлении фигурных скобок.
Паскаль Куок
113

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

if(one)
    if(two)
        foo();
    else
        bar();

Из этого:

if(one)
    if(two)
        foo();
else
    bar();
doynax
источник
8
Это гораздо более серьезная проблема, чем упомянутая в верхнем ответе (добавление второго утверждения).
3
действительно, этот ответ фактически отвел меня от циничного чтения этих ответов к умеренной обеспокоенности, что, возможно, я действительно совершил эту ошибку.
omikes
3
Если кому-то еще было интересно, каким образом C на самом деле интерпретирует его, тест, который я провел с GCC, интерпретирует этот код первым способом. tpcg.io/NIYeqx
Орта
3
"двусмысленность" - неправильный термин. Нет никакой двусмысленности в том, как синтаксический анализатор это увидит: elseобъект жадно привязывается к ближайшему, самому внутреннему if. Проблема возникает, когда C или подобные языки кодируются людьми, которые этого не знают, не думают об этом или еще не выпили достаточно кофе - поэтому они пишут код, который, по их мнению, будет делать что-то одно, но Спецификация языка говорит, что синтаксический анализатор должен делать что-то еще, что может сильно отличаться. И да, это еще один веский аргумент в пользу того, чтобы всегда включать фигурные скобки, даже если грамматика помечает их как теоретически «ненужные».
underscore_d
35

Мой общий шаблон таков: если он умещается в одной строке, я сделаю:

if(true) do_something();

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

if(true) {
    do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}

if(false) {
    do_something();
} else {
    do_something_else();
}

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

Matchu
источник
4
Хотя, как бы легко это ни было написать if(true){ do_something(); }, зачем рисковать, если другой программист внесет серьезную ошибку в будущем (найдите полную ошибку ssl-кода Apple "goto fail").
Крейг
9
Никакие скобки не освободят сопровождающего от использования своего мозга. Я поддерживаю идею «без скобок, если он умещается в одной строке», потому что, ну, для меня такой if является всего лишь версией тернарного оператора if, в котором не нужно ничего делать в части «после:» тройная. И зачем кому-то вводить скобки для троичного, если ?
Michal M
Я совершенно не согласен с тем, что в конечном итоге это субъективно и что это влияет только на стиль и удобочитаемость. Как человек, который потратил время на отладку проблем, которые, как выяснилось, были вызваны отсутствием разделителей блоков (и не замечая их отсутствия), мне пришлось использовать стиль кодирования, который пропускает их, когда они `` ненужны '' - и кто читал о многочисленных ужасные ошибки, очень вероятно, вызванные такими стилями кодирования - я думаю, что это очень объективный практический вопрос. Конечно, со стилем, предписывающим разделители, мы все еще можем их забыть, но, конечно, - по крайней мере, - мышечная память делает нас гораздо менее вероятными.
underscore_d
10

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

Мне нравится этот:

if (statement)
{
    // comment to denote in words the case
    do this;
    // keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
    do this;
}
Pentium10
источник
5
Это полностью субъективная проблема стиля, мне лично не нравится избыточность линий, содержащих только скобки. Но эй.
Matchu
14
Я поддерживаю этот стиль. Большинство людей читают код слева направо, и это как бы привязывает наши глаза к левому краю экрана. Это помогает визуально разделить и извлечь код на логические блоки шагов.
mloskot
6
Я всегда предпочитал этот стиль. Намного проще найти соответствующую закрывающую скобку. Так много места занимает? Используйте более мелкий шрифт.
timday,
4
Мне всегда легче «сканировать» код, когда фигурные скобки находятся на отдельных строках. Это касается всего; классы, методы, операторы if и while и т. д. Никогда не любил, когда первая дубль на одной линии ...
Свиш
2
Пробелы обходятся дешево, особенно когда у вас есть IDE с возможностью сворачивания кода.
Му
10

Я следую «правилу»:

Если оператор «if» выполняет тестирование, чтобы что-то сделать (функции вызова IE, переменные настройки и т. Д.), Используйте фигурные скобки.

if($test)
{
    doSomething();
}

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

Если оператор «if» выполняет тестирование, чтобы прекратить что-либо делать (управление потоком IE внутри цикла или функции), используйте одну строку.

if($test) continue;
if($test) break;
if($test) return;

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

Маркус Харрисон
источник
8

Наличие фигурных скобок с первого момента должно помочь вам никогда не отлаживать это:

if (statement)
     do this;
else
     do this;
     do that;
Мэтт Бишоп
источник
1
Кажется, это общепринятое объяснение, но (чтобы сыграть здесь адвоката дьявола) разве одно дополнительное правило выделения синтаксиса не решит эту проблему, сохранив при этом одну строку?
Кен
2
То же самое и с IDE, которая исправляет отступы при нажатии ;:)
Сэм Харвелл,
6

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

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}

Гораздо приятнее выглядит так:

someVar= someFlag ? 'someVal1' : 'someVal2';

Но используйте тернарный оператор только в том случае, если вы абсолютно уверены, что больше ничего не нужно добавлять в блоки if / else!

leepowers
источник
2

По моему опыту, единственное (очень) небольшое преимущество первой формы - читабельность кода, вторая форма добавляет «шума».

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

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

Одно из самых важных правил, которое следует помнить при написании кода, - это согласованность. Каждая строчка кода должна быть написана одинаково, независимо от того, кто ее написал. Строгость предотвращает "возникновение" ошибок;)

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

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

thomas.g
источник
2

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

if(statement)
{
    do this;
}
else
{
    do this;
}

Однако я думаю, что лучшее решение этой проблемы - в Python. С блочной структурой на основе пробелов у вас нет двух разных методов создания оператора if: у вас есть только один:

if statement:
    do this
else:
    do this

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

Грант Пол
источник
Я сам по себе считаю, что то, как Python обрабатывает операторы if-else, очень уродливо, но опять же, я не программист на Python (пока)
helpermethod
1

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

Не получится:

если (оператор) сделать это; и это; иначе сделайте это;

Джо
источник
1

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

Пример:

if (argument == null)
    throw new ArgumentNullException("argument");

if (argument < 0)
    return false;

В противном случае я использую второй стиль.

Нейт Генрих
источник
1

Лично я предпочитаю использовать сочетание пробелов и скобок, например:

if( statement ) {

    // let's do this

} else {

    // well that sucks

}

Я думаю, что это выглядит чистым и делает мой код очень простым для чтения и, что самое главное, - для отладки.

Саймон
источник
0

Я согласен с большинством ответов в том, что лучше указывать в коде явно и использовать фигурные скобки. Лично я бы принял набор стандартов кодирования и убедился бы, что все в команде знают их и соблюдают. Где я работаю, мы используем стандарты кодирования, опубликованные IDesign.net для проектов .NET.

Kane
источник
0

Я предпочитаю ставить фигурную скобку. Но иногда помогает тернарный оператор.

Вместо того :

int x = 0;
if (condition) {
    x = 30;
} else {
    x = 10;
}

Просто нужно сделать: int x = condition ? 30 : 20;

Также представьте себе случай:

if (condition)
    x = 30;
else if (condition1)
    x = 10;
else if (condition2)
    x = 20;

Было бы намного лучше, если бы вы вставили фигурную скобку.

fastcodejava
источник