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


177

Почему все говорят мне, что написание кода - это плохая практика?

if (foo)
    Bar();

//or

for(int i = 0 i < count; i++)
    Bar(i);

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

using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
{
    for (int x = 0; x <= GlowAmount; x++)
    {
        for (int y = 0; y <= GlowAmount; y++)
        {
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
        }
     }
 }
 //versus
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
    for (int x = 0; x <= GlowAmount; x++)
        for (int y = 0; y <= GlowAmount; y++)
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));

Вы также можете получить дополнительное преимущество от объединения в цепочку usingsбез необходимости делать отступы миллион раз.

using (Graphics g = Graphics.FromImage(bmp))
{
    using (Brush brush = new SolidBrush(backgroundColor))
    {
        using (Pen pen = new Pen(Color.FromArgb(penColor)))
        {
            //do lots of work
        }
    }
 }
//versus
using (Graphics g = Graphics.FromImage(bmp))
using (Brush brush = new SolidBrush(backgroundColor))
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
    //do lots of work
}

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

if (foo)
    Bar();
    Biz();

Вопросы:

  1. Не правильно ли хотеть использовать более компактный синтаксис, который предлагает язык? Люди, которые проектируют эти языки, умны, я не могу себе представить, что они добавят функцию, которой всегда плохо пользоваться.
  2. Должны ли мы или не должны писать код, чтобы наименьший общий знаменатель мог понять и без проблем работать с ним?
  3. Есть еще один аргумент, который я пропускаю?

6
Я согласен с тобой. Опустить их. Период.
Андрей Ринея

67
Кто заботится о том, как много линий в 2010 году. Мониторы широкие, дешевые и с высоким разрешением! Мой монитор 2048 X 1152, и у меня их два! Читаемость гораздо важнее, чем сохранение двух вертикальных линий, когда вы можете легко вносить тонкие ошибки, которые трудно найти.

51
Мониторы широкие и дешевые, но не высокие и дешевые. Вертикальное пространство более скудно, чем горизонтальное.
говорит Адам - ​​восстановите Монику

32
@AdamRuth Поверни их в сторону :)
Захари Йейтс

16
Так что вы не облажаетесь, как Apple, с ошибкой SSL, обнаруженной в феврале 2014 года, LOL.
учиться

Ответы:


183

На самом деле, единственное, что меня действительно поразило, это когда я отлаживал и комментировал bar ():

if(foo)
  // bar();
doSomethingElse();

Помимо этого, я склонен использовать:

if(foo) bar();

Который заботится о вышеупомянутом случае.

РЕДАКТИРОВАТЬ Спасибо за разъяснение вопроса, я согласен, мы не должны писать код с наименьшим общим знаменателем.


31
Это, конечно, грубо, но я думаю, что самая большая проблема для сопровождающих заключается в том, что они добавят вторую строку и не осознают, что это не является частью условного выражения, даже если оно ДЕЙСТВИТЕЛЬНО выглядит так, как должно быть.
Даниэльтальский

23
Мне не нравится стиль с одним вкладышем, потому что я всегда ищу тело петли ниже.
Носредна

18
Я считаю, что однострочный стиль скорее раздражает, чем помогает, потому что (особенно в глубокой вложенности - тьфу) утверждение может быть легко переоценено, и может возникнуть путаница. Я почти исключительно использую такие одиночные операторы if для проверки входных данных (т. Е. Ранних возвратов) или контроля цикла (например, игнорируя нерелевантные имена файлов при обходах файловой системы), хотя пустые строки помогают выделить их из основного кода.
Алан Плам

1
Однострочный стиль также скрывает bar () от тестового покрытия. Это будет выглядеть прикрыто, даже если foo всегда ложно.
Богумил Джанда

1
Это еще один способ сказать: «Если бы источник включал фигурные скобки, я бы не стал тратить время на отладку». - добавление фигурных скобок тривиально просто и позволяет избежать ловушек для следующего человека. Единственный аргумент против - это «читабельность», что довольно незначительно, учитывая, что это тот случай, когда что-то неявно происходит, если вы их опускаете.
Эндрю Текен

156

Скорость чтения ...

Помимо того, что уже было упомянуто. К этому моменту я уже был подготовлен к анализу операторов с фигурными скобками и пробелами. Итак, я прочитал:

if (condition)
{
    DoSomething();
}

DoSomethingElse();

Чуть быстрее, чем я читаю:

if (condition) DoSomething();

DoSomethingElse();

Я читаю это немного медленнее, если это выглядит так:

if (condition) DoSomething();
DoSomethingElse();

Я прочитал это значительно медленнее, чем предыдущий:

if (condition) 
    DoSomething();
DoSomethingElse();

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

if (condition)
{
    DoSomething();
    DoSomethingElse();
}

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

if (condition) 
    DoSomething();
    DoSomethingElse();

29
Проблема решается, когда в вашем 4-м примере вы просто помещаете пустую строку после оператора if, чтобы отделить его от DoSomethingElse (). Это то, что я делаю, и читаемость практически такая же, как в 1-м примере (если не лучше ;-P) Другое дело, что размещение строк в группы по 2 или 3 значительно улучшает читабельность, вы просто сканируете код намного быстрее.
Петр Овсяк

6
Может быть, это потому, что я привык к Python, но помещая первую фигурную скобку в ту же строку, что и оператор if, позволяет мне читать + понимать это еще быстрее.
Ponkadoodle

16
Проблема, связанная с бесстрастным стилем, заставляет вас тратить свою драгоценную концентрацию на размышления о том, есть ли у блока фигурные скобки, а не более важные вещи. Это само по себе является достаточно веской причиной, чтобы использовать простейшее соглашение, которое всегда заключено в фигурные скобки.
Nate CK

2
Брекеты явные по своей природе. Я буду придерживаться этого, спасибо.
TheOptimusPrimus

2
В последнем случае выследите первоначального автора и отшлепайте его ...;)
Per Lundberg

55

Если это что-то маленькое, напишите это так:

if(foo()) bar();

Если это достаточно долго, чтобы разбить на две строки, используйте скобки.


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

10
Не очень дружественный к отладчику, все же. Как вы устанавливаете точку останова на части «bar»?
Неманя Трифунович

9
@Nemanja: просто наведите курсор на панель (); и нажмите F9. И VS2005, и VS2008 обрабатывают внутристрочные точки останова, если они являются отдельными «операторами».
GalacticCowboy

4
GalanticCowboy: Есть больше сред, чем те, которые вы знаете. :-)

20
Конечно, но поскольку контекст C #, это должно охватывать значительное большинство пользователей ...
GalacticCowboy

47

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

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

if(a)
   if(b)
     c();
else
   d();

Заметили ли вы, что предложение else на самом деле относится к выражению if (b)? Вы, вероятно, сделали, но вы бы доверяли кому-либо, чтобы быть знакомым с этим Гоча?

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


12
Это один из двух случаев, когда я использую фигурные скобки. В противном случае нет.
Андрей Ринея

3
Это скорее должно быть написано так, как будто (a && b) ... во-первых, метинкс.
alexander.biskop

8
@ alexander.biskop: Конечно, нет, так как это дает блоку else другое значение ( !a || !b), чем с добавленными скобками ( !a) или без ( a && !b).
Бен Фойгт

1
@ Бен Фойгт: Правда! Это случилось ;-) Через полгода и два возражения кто-то понимает, что сделанное мной заявление неверно ... Думаю, я не уделял достаточно внимания деталям, главным образом потому, что намерение, стоящее за моим комментарием, было иным, чем указание технически правильное преобразование этого if-предложения. Я имел в виду, что вложенные встроенные операторы if, как правило, значительно снижают читабельность (и, в особенности, отслеживаемость потока управления), и поэтому их следует скорее объединить в один оператор (или вообще обойти). Приветствия
alexander.biskop

3
@ alexander.biskop: в то же время отладка проще с помощью вложенных if, каждый из которых имеет более простые условия, так как вы можете перейти на каждый шаг.
Бен Фойгт

35

Это не всегда считается плохой практикой. В Рекомендации Coding Mono Project предлагает не использовать фигурные скобки , если это не нужно. То же самое для стандартов кодирования GNU . Я думаю, что это вопрос личного вкуса, как всегда, со стандартами кодирования.


2
Глядя на код Mono, мне кажется совершенно чуждым после прочтения всего руководства.
dance2die

35

Линии дешевые. Мощность процессора дешевая. Время разработчика очень дорого.

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

(a) Легко для любого другого разработчика следить за тем, что я делаю

(б) Прокомментируйте конкретные части кода, которые могут понадобиться

(c) Легко отлаживать, если что-то идет не так

(d) Легко изменить, если это необходимо в будущем (например, добавление / удаление кода)

Скорость или академическая элегантность кода являются вторичными по отношению к этим факторам с точки зрения бизнеса. Это не значит, что я решил написать неуклюжий или уродливый код, но это МОЙ порядок приоритетов.

Опуская фигурные скобки в большинстве случаев, это делает для меня (b), (c) и (d) более трудным (однако, примечание не является невозможным). Я бы сказал, что использование фигурных скобок или нет не влияет на (а).


9
Ваше последнее утверждение о (а) - это мнение, что большое количество разработчиков, включая другие постеры здесь, будут спорить.
Келли С. Френч

34

Я предпочитаю ясность, которую предлагает фигурная скобка. Вы точно знаете, что имеется в виду, и вам не нужно догадываться, просто ли кто-то обманул и оставил их (и добавил ошибку). Единственный раз, когда я их опускаю, это когда я помещаю действия if и if в одну строку. Я тоже так делаю не очень часто. Я на самом деле предпочитаю пропуски, введенные в виде фигурной скобки в отдельной строке, хотя после многих лет программирования, подобного K & R C, окончание строки фигурной скобкой - это практика, которую мне нужно преодолеть, если в среде IDE ее не применяют для меня.

if (condition) action();  // ok by me

if (condition) // normal/standard for me
{
   action();
}

23

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

Я обычно опускаю их, когда они не нужны, за исключением следующих случаев:

if (something)
    just one statement; // i find this ugly
else
{
    // many
    // lines
    // of code
}

я предпочитаю

if (something)
{
    just one statement; // looks better:)
}
else
{
    // many
    // lines
    // of code
}

15

Один из случаев, когда это может вас укусить, - это в старые времена макросы C / C ++. Я знаю, что это вопрос C #, но часто стандарты кодирования переносятся без причин, по которым стандарт был создан в первую очередь.

Если вы не очень осторожны при создании макросов, вы можете столкнуться с проблемами в операторах if, которые не используют {}.

#define BADLY_MADE_MACRO(x) function1(x); function2(x);

if (myCondition) BADLY_MADE_MACRO(myValue)

Не поймите меня неправильно, я не говорю, что вы всегда должны делать {}, чтобы избежать этой проблемы в C / C ++, но мне пришлось столкнуться с некоторыми очень странными ошибками из-за этого.


2
если бы весь код объявил себя таковым ... вздох
Натан Стронг

15

Я привык думать так же.

До одного дня (почему всегда есть тот «один день», который навсегда меняет вашу жизнь?) Мы тратим от 24 до 36 часов подряд, не отлаживая рабочий код, только чтобы обнаружить, что кто-то не поставил фигурные скобки в сочетании с изменением поиска / замены ,

Это было что-то вроде этого.

 if( debugEnabled ) 
      println( "About to save 1 day of work to some very important place.");
 saveDayData();

Что было после того, как

 if( debugEnabled ) 
 //     println( "About to save 1 day of work to some very important place.");
 saveDayData();

Оказывается, что система генерировала 500 МБ журналов в день, и нас попросили остановить это. Флаг отладки был недостаточен, поэтому поиск и замена println были в порядке.

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

РЕДАКТИРОВАТЬ

Теперь единственное место, где я не использую фигурные скобки - это if / try construct.

if( object != null ) try { 
     object.close();
} catch( .....

После просмотра суперзвезда разработчик делает это.


3
Я не понимаю У вас есть переменная, которая управляет отладкой (debugEnabled), и вы все еще используете комментарии, чтобы отключить отладку ??? Почему вы просто не установили для debugEnabled значение false?
Игорь Попов

Это не совсем сценарий, но вы делаете хорошее замечание. Глупые вещи (например, не устанавливая debug в false) создают тонкие и глупые ошибки, которые труднее найти, чем «очевидные» ошибки. Не использование скобок не очень помогло в этом случае.
ОскарРиз

1
@igor Как насчет того, потому что они просто хотели удалить одну строку журнала, а не все строки журнала?
Ган

14

Чтобы быть тупым, я вижу это как:

Хорошие программисты программируют в обороне, плохие программисты - нет.

Так как есть несколько примеров выше и мой собственный похожий опыт с ошибками, связанными с забвением фигурных скобок, то я научился трудному пути ВСЕГДА РАЗМЕЩАТЬ БРАСЫ.

Все остальное - это выбор личного стиля, а не безопасности, и это явно плохое программирование.

Джоэл даже упоминает об этом в «Неправильный код выглядит неправильно»

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


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

14

Я очень рад:

foreach (Foo f in foos)
  foreach (Bar b in bars)
    if (f.Equals(b))
      return true;

return false;

Лично я не понимаю, почему

foreach (Foo f in foos)
{
  foreach (Bar b in bars)
  {
    if (f.Equals(b))
    {
      return true;
    }
  }
}

return false;

более читабелен.

Да, строки свободны, но почему я должен прокручивать страницы и страницы кода, когда он может быть вдвое меньше?

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

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

if (condition1)
  if (condition2)
    doSomething();
  else (condition2)
    doSomethingElse();

против

if (condition1)
  if (condition2)
    doSomething();
else (condition2)
  doSomethingElse();

ужасно сбивает с толку, поэтому я всегда пишу это как:

if (condition1)
{
  if (condition2)
    doSomething();
  else (condition2)
    doSomethingElse();
}

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


только что видел, что это почти что происходит в моем коде :) подумал, что я посмотрю вокруг, и о чудо ... это уже там :)
Noctis

10

Я согласен с тем, что «если вы достаточно умны, чтобы заставить кого-то платить вам за написание кода, вы должны быть достаточно умны, чтобы не полагаться только на отступы, чтобы увидеть поток кода».

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


10

Моя философия такова: если это делает код более читабельным, почему бы не сделать это?

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

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


7
Конечно это очень субъективно. Оставляя их выключенными, иногда улучшается читаемость.
Брайан Кноблаух

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

10

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

if(x == y)
   for(/* loop */)
   {
      //200 lines
   }

//rampion's example:
for(/* loop */)
{
   for(/* loop */)
      for(/* loop */)
      {
         //several lines
      }
}

В противном случае у меня нет проблем с этим.


4
Плохие примеры. В обоих случаях я бы выделил 200 строк для цикла в свой собственный метод или, желательно, несколько методов.
Адам Яскевич

2
Правда, но это случается. Кроме того, каждый раз, когда блок длиннее экрана читателя, у вас возникнет эта проблема. И вы не можете контролировать высоту экрана вашего читателя кода. Они могут видеть только пару строк на каждой стороне.
Сезон

2
Это случается Это не значит, что это должно произойти.
Адам Яскевич

3
@AdamJaskiewicz Верно. Это случается Мы должны думать о том, что происходит, а не о том , что должно произойти. Если бы мы могли ограничиться тем, что должно произойти, нам не пришлось бы беспокоиться об ошибках.
Беска

10

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

Я видел

if (...)
    foo();
    bar();

ошибка кусает меня (точнее, «я и коллеги» - я фактически не представлял ошибку) один раз . И это несмотря на то, что наши стандарты кодирования в то время рекомендовали использовать фигурные скобки везде. Мне потребовалось удивительно много времени, чтобы увидеть - потому что вы видите то, что хотите видеть. (Это было около 10 лет назад. Возможно, я бы нашел это быстрее сейчас.)

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


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

@Bob: Хороший вопрос, и я делаю это только изредка. Я не хотел бы делать вид , что у меня есть реальные причины здесь :) На самом деле, есть разумная причина - гнездовье в usings (и только usings) , как , что довольно очевидно, и вы до сих пор в конечном итоге с в блоке. Я не могу сразу увидеть опасность.
Джон Скит

Который не должен сказать , что это не какая -то опасность, конечно.
Джон Скит

1
Лучшее решение этой ошибки: используйте Python. (Шучу, конечно.)
Джоэль Вительманн

10

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

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

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

Тем не менее, в мире изменились некоторые вещи, которые делают правило «используйте скобки на однолинейных блоках» менее актуальным сегодня, чем когда Моисей довел его до нас:

  • Некоторые популярные языки устраняют проблему, заставляя компьютер читать отступы, как это делает программист (например, Python).

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

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

  • Рефакторинг и языковая выразительность означают, что мои блоки намного короче, а однострочные блоки встречаются гораздо чаще, чем раньше. Гипотетически, с безжалостным применением ExtractMethod, я мог бы иметь только однострочные блоки во всей моей программе. (Интересно, как это будет выглядеть?)

На самом деле, есть явная выгода от беспощадного рефакторинга и пропуска фигурных скобок в однолинейных блоках: когда вы видите фигурные скобки, в вашей голове может возникнуть небольшая тревога, которая говорит: «Сложность здесь! Остерегайтесь!». Представьте, если это было нормой

if (condition) Foo();   // normal, everyday code

if (condition) 
{
    // something non-trivial hapening; pay attention!
    Foo();
    Bar();
}

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


Как бывший Java-программист, я должен полностью согласиться с тем, что автоматическое форматирование является реальным решением проблемы. Вам даже не нужно, чтобы ваш редактор автоматически добавлял фигурные скобки - само по себе автоматическое выравнивание может помочь избежать двусмысленности. Конечно, теперь, когда я перешел на Python, я привык к правильному форматированию кода.
Алан Плам

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

9

Из трех конвенций:

if(addCurleyBraces()) bugFreeSofware.hooray();

и:

if(addCurleyBraces())
    bugFreeSofware.hooray();

и (которые представляют любой стиль отступа, используя открывающую и закрывающую скобки):

if(addCurleyBraces()) {
    bugFreeSofware.hooray();
}

Я предпочитаю последний как:

  • Мне легче читать, если все операторы if написаны одинаково.
  • Это может сделать программное обеспечение чуть более надежным и без ошибок. Тем не менее, все современные IDE и расширенные текстовые редакторы имеют прекрасные функции автоматического отступа, которые, я думаю, должен использовать каждый, если это не мешает форматированию комментариев или не соответствует групповым стандартам (во многих случаях можно создать собственную схему форматирования). и поделиться этим с командой). Моя точка зрения заключается в том, что, если отступы выполнены правильно, риск появления ошибки немного снижается.
  • Я предпочитаю, чтобы логические выражения и операторы выполнялись в разных строках. Мне нравится иметь возможность пометить строку в целях отладки. Даже если я использую IDE, где я могу пометить оператор и перейти к нему, это интерактивная операция, и я могу забыть, где я начал отлаживать, или, по крайней мере, мне потребуется немного больше времени, чтобы пройти по коду несколько раз. раз (так как я должен отмечать позицию вручную каждый раз во время отладки).

8

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

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

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


8

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

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

if(x < y)
    x = y;
else
    y = x;

И другой, как это;

if(x < y)
{
    x = y;
    x++;
}
else
{
    y = x;
    y++;
}

Я предпочитаю просто выбрать один общий стиль и придерживаться его :)


7

Одна из основных проблем - это когда у вас есть области с одним и не одним вкладышем, а также отделение от контрольного статута ( forи того if, что у вас есть) и конец статуата.

Например:

for (...)
{
  for (...)
    for (...) 
    {
      // a couple pages of code
    }
  // which for block is ending here?  A good text editor will tell you, 
  // but it's not obvious when you're reading the code
}

4
Почему в вашем цикле for есть пара страниц кода?
Адам Яскевич

b / c Я нечувствительный ком, и я одержим избавлением от "стоимости" вызовов функций. :)
rampion

4
Обычно пара страниц кода должна быть в отдельной функции.
Джонатан Леффлер

1
извините, я имел в виду, что играл роль такого кома. Тем не менее, я считаю, что та же проблема может возникнуть в более коротких регионах при просмотре через небольшое окно просмотра. И это вне контроля кодера.
Рэмпион

7

Раньше я был большим сторонником «фигурные скобки - это НЕОБХОДИМО!», Но с тех пор, как я начал использовать модульное тестирование, я обнаружил, что мои модульные тесты защищают беспрепятственные утверждения от таких сценариев, как:

if (foo)
    snafu();
    bar();

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

В качестве альтернативы, для чего-то подобного выше, я бы, скорее всего, добавил это так:

if (foo) snafu();

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


2
Вы сказали: «Мне это не нужно», а затем назвали причину его использования: удобочитаемость!
tvanfosson

4
Я бы не стал полагаться на юнит тест, чтобы найти это. LINT возможно, модульного теста нет!
Кристен

2
@Kristen - Идея модульного теста состоит в том, чтобы подтвердить поведение метода. Если поведение изменяется (как описано выше), модульный тест не пройден. Я не вижу проблемы в этом.
Liggy

Но зачем полагаться на модульное тестирование, чтобы выявить очевидное, что должно быть исправлено, прежде чем идти в UT?
Андрей

7

Используйте некоторые личные суждения.

if (foo)
  bar();

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

if (foo)
  bar();
  baz();

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

В обмен это намного более читабельно.

Оставшееся время:

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

Который был моим любимым, насколько я помню. Дополнительно:

if (foo) {
  bar();
  baz();
} else {
  qux();
}

Работает для меня.

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


Единственный раз, когда я предпочитаю первый стиль, это когда мне нужно немедленно вернуться или выдать ошибку, если что-то не так. Как if (parameter == null) return null;.
nawfal

7

Хорошо, это старый вопрос, на который был дан ответ до смерти. Мне есть что добавить.

Во-первых, я просто должен сказать, ИСПОЛЬЗУЙТЕ КРЕСТОВ. Они могут только помочь читаемости, и читаемость (для вас и других!) Должна быть очень высокой в ​​вашем списке приоритетов, если вы не пишете сборку. Нечитаемый код всегда, всегда приводит к ошибкам. Если вы обнаружите, что скобки заставляют ваш код занимать слишком много места, ваши методы, вероятно, слишком длинные. Большинство или все методы должны умещаться в пределах одной высоты экрана, если вы все делаете правильно, и Find (F3) - ваш друг.

Теперь для моего дополнения: есть проблема с этим:

if (foo) bar();

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

Так что сделайте это:

if (foo)
{
    bar(); //It is easy to put a breakpoint here, and that is useful.
}

2
Щелкните правой кнопкой мыши на панели и выберите «Вставить точку останова ... Не сложно». Знай свои инструменты.
Боб

Щелчок правой кнопкой мыши по индикатору ничего не дает; Вы имеете в виду щелчок правой кнопкой мыши по тексту? В любом случае, если вы хотите, чтобы точка останова была достигнута только тогда, когда выражение «если» истинно, а «bar ()» находится на отдельной строке, вы можете поместить курсор в любое место этой строки и нажать клавишу F9 или щелкнуть левой кнопкой мыши индикатор маржи. Однако, если весь код находится в одной строке, вам нужно поместить курсор на «bar ()» или щелкнуть правой кнопкой мыши точно там, прежде чем нажимать F9, и нажатие поля индикатора не будет работать (ставит точку останова на « если'). Это не «сложно», но требует меньше концентрации, когда код состоит из двух строк.
камень

О, ха-ха, щелкните правой кнопкой мыши на "bar ()." Вы имели в виду текст. Попался. Конечно, или просто нажмите F9 ...
камень

>> Вы должны поместить курсор на «bar ()» или щелкнуть правой кнопкой мыши точно там, прежде чем нажимать F9, (я имел в виду позиционировать курсор точно там, прежде чем либо нажать F9, либо щелкнуть правой кнопкой мыши)
камень

7

чтобы код с фигурными скобками не занимал много места, я использую технику, рекомендованную в книге « Код завершен» :

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

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

2
Это более известный как стиль K & R. Основано на книге Кернигана и Ричи «Язык программирования Си»: en.wikipedia.org/wiki/The_C_Programming_Language_(book) . И это не должно вас унизить.
jmucchiello

Спасибо! Я полагал, что это был только личный вкус. Раньше я находил этот синтаксис раздражающим, но принял его после прочтения Code Complete, и теперь мне действительно нравится.
Натан Пратер

Я читал все ответы выше этого, думая: «Почему никто еще не предложил это ???» Это выравнивает закрывающую скобку с блоком, который она закрывает, то есть «если» или «пока» и т. Д., А не бессмысленно «{». +1.
Nickf

Если открытые скобки всегда помещаются в строки сами по себе, то знак, ifза которым следует одна строка с отступом, может визуально распознаваться как управляющий одним оператором без необходимости в каких-либо скобках. Таким образом, стиль «открытая скобка сам по себе» экономит пустое пространство в ситуации, когда ifоператор управляет чем-то, что является семантически единственным действием (в отличие от последовательности шагов, которая содержит только один шаг). Например, if (someCondition)/ `throw new SomeException (...)`.
суперкат

6

Допустим, у вас есть код:

if (foo)
    bar();

а потом приходит кто-то еще и добавляет:

if (foo)
    snafu();
    bar();

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


Эта точка зрения уже была высказана в вопросе.
Майк Скотт

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

Есть ли такая вещь, как код ошибки?
Боб

Нет, но вы можете сделать это сложнее. Прочитайте «Лучшие секреты рецензирования кода» Джейсона Коэна (см. Ссылку на боковой части некоторых страниц здесь), чтобы лучше понять, почему вы это делаете.
Elie

Кто этот Майк Скотт и почему он ответит полиции? Меня всегда раздражает, что люди должны заявить, что очевидно. Так почему же Майк не стал комментировать добавленное описание, которое пользователи публикуют об этой проблеме? Разве не все ответы относятся к вопросу?
Bruceatk

6

Сокращение строк не очень хороший аргумент для удаления скобок. Если ваш метод слишком велик, его, вероятно, следует реорганизовать в более мелкие части или реструктурировать. Это, несомненно, повысит читабельность больше, чем просто удаление скобок.


5

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

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

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


4

В большинстве случаев это укоренилось в качестве стандарта кодирования, будь то для компании или проекта FOSS.

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

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


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

3

Ошибка на стороне более безопасного - только еще одна ошибка, которую вам потенциально не придется исправлять.

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

Если у меня есть одна строка, я обычно форматирую ее следующим образом:

if( some_condition ) { do_some_operation; }

Если строка слишком громоздкая, используйте следующее:

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