#синтаксис #code_style
Здравствуй, я не понимаю зачем все говорят что нужно всегда использовать { и } Вот например код: if(1>2) { test = true; } Зачем тут писать скобки? Многие говорят что для читаемости, но любой программист знает о таком написании, зачем же увеличить код? Так же лично я не понимаю зачем открытие скобки писать на новой строке, что бы занять ещё одну лишнюю строку? На мой взгляд это неправильно, возможно вы меня сможете в этом переубедить? Лично мне намного быстрее и удобнее разобрать вот такой код: if ($a === $b) bar(); elseif($a > $b) $foo->bar($arg1); else BazClass::bar($arg2, $arg3); Чем: if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); }
Ответы
Ответ 1
Ответ на самом деле зависит от языка. Некоторые языки (javascript, I'm looking at you) практически требуют специальной расстановки скобок, в их отсутствие код может распарситься неочевидным образом. В остальных языках-с-фигурными-скобками (C/C++/Java/C#/...) расстановка скобок — личное дело каждого, вопрос вкуса. Я лично стараюсь опустить скобки где только возможно, например, в коде if (x > 0) x = -x; Другим, наоборот, нравится наличие скобок, так как это позволяет коду if (x > 0) { x = -x; } if (y > 0) { y = -y; z = x; } выглядеть однообразно. Мой совет — пишите код так, чтобы форматирование подчёркивало вашу мысль. Например, симметрию внутренних структур кода. Это самое главное. Наличие или отсутствие скобок не сделают вас плохим программистом, отсутствие стиля вполне может. Важный отдельный случай — это наличие общего стиля команды. Если во всей команде принято ставить (или не ставить) дополнительные скобки, вам придётся придерживаться общего стиля.Ответ 2
Практика всегда ставить скобки избавляет вас от досадных глупых ошибок. Страшилка 1. Жил-был метод с guard condition: if(somethingBad()) return; В один прекрасный день вы собираетесь домой, вас просят быстренько добавить логгирование туда. Ткнули по кнопкам (может быть даже по хоткею для live template), закоммитили: if(somethingBad()) log.error("Something bad happened"); return; И ушли. А кто-то потом тратит пару часов, чтобы найти эту невзрачную ошибку. Страшилка 2. Жил был код: if (reallyRareCondition()) handleIt(); doImportantThings(); Однажды джуниора попросили временно убрать обработку Очень Редкого Случая. Он смело закомментировал соответствующую строку и ушел играть в кикер с коллегами. if (reallyRareCondition()) // handleIt(); doImportantThings(); А потом вдруг Что-то Очень Важное перестало работать кроме редких случаев. PS. Все совпадения не случайны, а действующие лица не выдуманы.Ответ 3
Лично я не понимаю зачем открытие скобки писать на новой строке, что бы занять ещё одну лишнюю строку? Наличие скобок и способ их расстановки это не просто вопрос стиля или личных предпочтений. Сейчас многие удивяться, но в javascript код в зависимости от расстановки скобок выполняется по разному. Смотрите фокус: function sample1() { return { foo: 'test' }; } function sample2() { return { foo: 'test' }; } alert(sample1()); // object alert(sample2()); // undefined! и это не баг :)Ответ 4
зачем писать скобки. это от языка программирования зависит. В с/с++ скобки можно не писать, если дальше будет один оператор. А в от в перл в подобной конструкции скобки нужно писать (если только не инфиксный оператор), потому что там такой синтаксис. Но некоторые считают, что писать нужно в любом случае - так как в будущем может появится ещё одна строка внутри if и придется дописывать скобки. Так же лично я не понимаю зачем открытие скобки писать на новой строке, что бы занять ещё одну лишнюю строку? тут нужно отталкиваться от стандартов, принятых в Вашей компании или личных предпочтений (для своего кода). На мой взгляд это неправильно, возможно вы меня сможете в этом переубедить? на мой взгляд, правильнее писать указанный код так: if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } А Ваши два варианта не пройдут кодревью. Но зачем мне Вас переубеждать. Пока Вы пишете код для себя - пишите как хотите, хоть по слову на строку. А вот когда пишете код для компании - тут нужно следовать правилам. Зарплата может быть хорошим инструментом переубеждения.Ответ 5
if(1>2) { test = true; } Зачем тут писать скобки? Лично я в таких случаях обычно не ставлю. Могу поставить, если дальше идёт блок else со скобками, да и то не всегда. Почти всегда ставлю в js (и джаве) - там, где принято стаить открывающую на той же строке. Многие говорят что для читаемости, но любой программист знает о таком написании, зачем же увеличить код? Дело в том, что такие выражения как правило идут среди другого кода, а не сами по себе. Соответственно, скобки явно выделяют блок, который относится к условию. Например: DoSmth1(); DoSomeOtherMagic(); if(x>7) Logger.Log(x); DoSmth(x, 2, 12, y, temp); DoALotOfOtherStuff(x); С какой вероятностью, радактируя этот код, можно случайно неправильно внести строчку в if или закомментировать имеющуюся там? Мне тоже рассказывали про реальные случаи, что комментировали логирование и следующая команда попадала в if. Как же пытаются решить эту проблему? Говорят, всегда ставим скобки. В таком случае получеается такой код: DoSmth1(); DoSomeOtherMagic(); if(x>7) { Logger.Log(x); } DoSmth(x, 2, 12, y, temp); DoALotOfOtherStuff(x); Да, здесь уже значительно сложнее ошибиться и как-то не так поступить с этим блоком. Но написан ли этот код красиво? На мой взгляд, нет. Это по прежнему мешанина вызовов методов и проверки условия. Причём, блок кода мы выделили, но таким образом мы ещё и отдалили вызываемый метод от условия. А вот как бы я отформатировал этот же код: DoSmth1(); DoSomeOtherMagic(); if(x>7) Logger.Log(x); DoSmth(x, 2, 12, y, temp); DoALotOfOtherStuff(x); Здесь нет скобок, но я потратил те же две строки, чтобы сделать вертикальные отступы. При редактировании такого кода, по сравнению с первым, гораздо сложнее ошибиться при его изменении, блок с условием заметно отделяется от остального кода, а содержимое блока идёт рядом с условием, а не отодвингается от него при помощи скобок. зачем все говорят что нужно всегда использовать { и } Потому что это проще сказать. Сказать, "пишите код в читаемом виде" - это как ничего не сказать - автор почти всегда скажет, что его код читаемый. А обговаривать все условия - это сложно. Например, я всегда ставлю скобки, если есть вторая строка - даже если она комментарий. Сейчас почти для всех языков IDE имеют автоформатирование. Для чего? Для того ли, чтобы было быстрее писать код? Или всё-таки для того, чтобы более или менее читаемый код мог писать кто угодно? Почему чем язык распространённее (и, в некоторой мере, проще), тем строже правила автоформатирования? Посмотрим на дефаултные настройки в Visual Studio. Для C++ (если я не ошибаюсь) нет автоматического добавления пробелов вокруг бинарных операторов. В C# есть. В VB.NET принудительное жёсткое форматирование отступов при уходе со строки. Случайность ли это? Вот мне кажется, что вряд ли. Почему предлагается всегда ставить пробелы у бинарных операторов? Какой вариант читаемее y = a*x*x + b*x + c; или y = a * x * x + b * x + c;? На мой взгляд первый. Тогда зачем? Да чтобы защититься от такого: y=a*x*x+b*x+c;. Так же и со скобками - это лёгкий путь предотвратить ошибки. Но лёгкий - не значит лучший. В IDE всё больше фич автоформатирования (которые, кстати, иногда бесят, когда ты хочешь внести изменение в одну строчку, а файл отформатирован не под текущий профиль), но вот отступы в виде пустых строк сами делаться не умеют. Да и в стайл-гайдах очень редко это прописывается. Точнее, часто для css и подобных, возможно ещё, отступы между функциями, но больше ничего не упоминается. Выравнивание кода в столбцы (про которое тоже недавно был вопрос) тоже упоминается крайне редко. Ну и ещё примерчик. Что лучше? if(user.HasRole("Admin")) { return SomeAdminData(); } if(user.HasRole("Moderator")) { return SomeModeratorData(); } if(user.HasRole("User")) { return SomeData(); } return SomeAnonimousData(); или всё-таки if(user.HasRole("Admin")) return SomeAdminData(); if(user.HasRole("Moderator")) return SomeModeratorData(); if(user.HasRole("User")) return SomeData(); return SomeAnonimousData(); но мне бы как-то не хотелось увидеть if(user.HasRole("Admin")) return SomeAdminData(); if(user.HasRole("Moderator")) return SomeModeratorData(); if(user.HasRole("User")) return SomeData(); return SomeAnonimousData(); потому что тут сложно зацепиться глазами за блоки. Кстати, как вариант, тут может быть if(user.HasRole("Admin")) return SomeAdminData(); if(user.HasRole("Moderator")) return SomeModeratorData(); if(user.HasRole("User")) return SomeData(); /*Anonimous*/ return SomeAnonimousData(); Но с этим подходом надо быть осторожным и использовать только тогда, когда это имеет смысл. Кстати, с этим вариантом могут быть проблемы с автоформатированием в IDE. Потому что я бы однозначно не хотел увидеть if(user.HasRole("Admin")) return SomeAdminData(); if(user.HasRole("Moderator")) return SomeModeratorData(); if(user.HasRole("User")) return SomeData(); /*Anonimous*/ return SomeAnonimousData(); такой вариант вообще нечитаемый. Так же лично я не понимаю зачем открытие скобки писать на новой строке Скобки на новой строке удобны тем, что видно, к какому блоку они относятся. Следующий код читаем. Он читаем даже если скобки по какой-то причине съедут. for(q=0; q$b) $foo->bar($arg1); else BazClass::bar($arg2, $arg3); Во-первых, если понадобится просматривать структуру кода, то это не слишком удобно читать. В смысле, если ты детально просматриваешь метод и читаешь полностью каждую строку, то всё хорошо. Но если ты просто бегло смотришь код, пытаясь понять, где и что используется, то совмещение условия с вызываемым методом может оказаться неудобным. Во-вторых, здесь нельзя поставить breakpoint на вызов метода. Так что отладке может помешать. Сам использую запись в одну строку только иногда в VB, где есть синтаксис однострочного if. Чем: if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } А вот такой стиль я виду впервые. Видел такое: if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } такое if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } и такое if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } Но вот вариант, когда открывающаяся скобка на отдельной строке, а закрывающаяся перед else - это что-то странное. Тоже не понимаю, зачем. Ответ 6
Включаем истерику Так же лично я не понимаю зачем открытие скобки писать на новой строке, что бы занять ещё одну лишнюю строку? БОЖЕЧКИ БОЖЕЧКИ ЛИШНЯЯ СТРОКА ЗАЙМЕТСЯ ЭТО ЖЕ ЕЩЕ НЕСКОЛЬКО БАЙТ ПО СЕТИ ПЕРЕДАВАТЬ ПОЖАЛУЙ, НЕ БУДУ СТАВИТЬ ЭТУ СКОБКУ Многие говорят что для читаемости, но любой программист знает о таком написании, зачем же увеличить код? ЛЮБОЙ ПРОГРАММИСТ ЗНАЕТ, ЧТО МОЖНО НАПИСАТЬ КОД В ОДНУ СТРОЧКУ, А ПЕРЕМЕННЫЕ МОГУТ БЫТЬ И В ОДИН СИМВОЛ if($a===$b)bar();elseif($a>$b)$f->b($arg1);else Bz::br($a2,$3); МММММ КАКАЯ ВКУСНАЯ ЭКОНОМИЯ БАЙТОВ Если серьезно, то разве вы хоть что-то делаете лучше, избавляясь от лишних пробелов и скобок? Вы же вообще ничего не экономите, ну совсем ничего. Про страшилки и общепринятый PSR уже рассказали.Ответ 7
Ну и в завершение нашего цирка, вот вам на ночь очень мудрый пример обращения со скобками. Когда этот код был Явой. доказательство public class Permuter { private static void permute(int n, char[] a) { if (n == 0) { System.out.println(String.valueOf(a)) ;} else { for (int i = 0; i <= n; i++) { permute(n-1, a) ; swap(a, n % 2 == 0 ? i : 0, n) ;}}} private static void swap(char[] a, int i, int j) { char saved = a[i] ; a[i] = a[j] ; a[j] = saved ;}}Ответ 8
Немного опоздал на вечеринку, но все равно зайду. ТС смотри глубже, зачем вообще нужны if, else, эти дурацкие переводы строк, точки с запятой фигурные скобки и знаки доллара если есть старый добрый тренарный условный оператор. (a==b) ? c() : (a>b) ? d.c(f) : e.c(g,h);Ответ 9
Есть стандарты кода, например PSR. Если предыдущий программист придерживался стандартов, то вы будете легче и быстрее читать написанный им код. Почему легче и быстрее? Потому что ваш мозг - это тот же компьютер. В случае обработки стандартных операций (шаблонов) затрачивается меньше ресурсов на их обработку.Ответ 10
Есть такие программисты-зануды, которые пользуются отладкой кода в ide. И если Вы хотите чтобы они каждый раз, когда захотят поставить точку остановы, вспоминали Вас, то пишите в одну строчку и икота с красными ушами Вам обеспечена!Ответ 11
Если вам не нравятся скобки, возможно вам стоит выбрать в качестве языка Python. Там с вами полностью солидарны :) if a == b: print('a == b') elif c == d: print('c == d') else print(':)')Ответ 12
Зачем тут писать скобки? На этот вопрос уже дан хороший ответ. Так же лично я не понимаю зачем открытие скобки писать на новой строке, что бы занять ещё одну лишнюю строку? Зачем писать открытие скобки на новой строке? Сейчас я пишу открытие скобки на новой строке, потому что это соответствует выбранному на данный момент стилю написания и, следовательно, повышает читабельность кода. Тема о преимуществах и недостатках тех или иных стилей слишком обширна и спорна, чтобы затрагивать ее здесь. Зачем писать открытие скобки на той же строке? Долгое время я писал открытие скобки на той же строке, потому что так безопаснее. Приходится иногда видеть такие ошибки (и сам я грешен был): if(1>2); { test = true; } Заканчивать строку точкой с запятой настолько естественно в C/C++, что иногда это делается на бессознательном уровне. Однако, если ставить открытие скобки на новой строке, то появляются строки, которые нельзя закрывать точкой с запятой, потому что это может привести к трудно отлавливаемой логической ошибке. Чтобы такие строки не появлялись, лучше писать так: if(1>2) {; test = true; } Тогда даже лишняя точка с запятой не приведет к ошибке. Да она скорее всего даже не появится, потому что после открывающей скобки бессознательного желания ставить точку с запятой нет. По крайней мере мне такой код видеть не приходилось. P.S. Те, кто не брезгует макросами, могут сочетать открытие скобки на новой строке и безопасность. Например так: #define FOR_S( ... ) for( __VA_ARGS__ ) { #define END_FOR_S } #define IF_S( ... ) if( __VA_ARGS__ ) { #define END_IF_S } #define ELSE_S } else { #define ELSE_IF_S } else IF_S #define WHILE_S( ... ) while( __VA_ARGS__ ) { #define END_WHILE_S } Тогда код с макросами будет выглядеть так: IF_S( toWorkWithA ); { makeAInput(); sendtoA(); } END_IF_S; Лишняя точка с запятой не приведет к ошибке. Однако: а) использование макросов тоже не безопасно, б) для кого-то замена ключевых слов на макросы может влиять на читабельность кода в худшую сторону.
Комментариев нет:
Отправить комментарий