Страницы

Поиск по вопросам

воскресенье, 24 ноября 2019 г.

Как писать красивый и читаемый код?



Максимальное сокращение кода.
Бывает желания максимально сократить код, но появляются сомнения, не перебор ли это
Ведь можно было бы  отдельно объявить переменную и ей уже присвоить выражение, которо
без переменной не сразу понятно что делает.
Именование переменных.
Проблемы с выбором имени для переменной. Если описывать полностью, что она делает
то будет около 16 символов, а если сокращать, то может конфликтовать с пониманием други
переменных. Контекст тоже не всегда спасает.
Разделение действий.
Слишком много всего в одной части кода, что может усложнить понимание. С одной сторон
можно было бы вынести в отдельные функции, а с другой стороны нет смысла, так как используютс
только в той части кода.
Уместность комментариев.
Свой код всегда понятен, а предположить как его понимают другие, будет не всегд
объективно. Так что, не всегда очевидно, нужен комментарий или он будет избыточен. 
Форматирование.
С большой или маленькой буквы начинать переменную, а также в пределах переменно
нужно ли большими буквами начинать слова или же разделять их с помощью "_". Делать л
пустую строку между if и другими блоками, а также между переменными и этими блокам
или же расставлять по действиям. Делать ли отступы внутри выражений, к примеру if( sometrin
) или if(sometring).
6...


Эти пункты только для понимания проблемы, потому что многие забыл, а многие и н
замечал, думаю. А также на эти пункты с одной стороны очень легко ответить, а с друго
хотелось бы правил или детального разбора.
Так вот, есть ли правила гласные/негласные, в которых бы описывалось это и много
другое в этом направлении? Или есть книги посвященные этой теме?
    


Ответы

Ответ 1



Вопрос стиля — на самом деле очень серьёзный вопрос. Не забывайте, что код пишется вами не для компилятора. Сделать, чтобы было понятн компилятору просто, но ваша цель сложнее: сделать так, чтобы было понятно человеку. Код программы — то же самое литературное произведение. Вы должны донести мысль читателю причём этим читателем можете оказаться как вы сами через полгода, так и ваш коллега которому придётся править код пока вы в отпуске. Хороший код живёт долго, а значит, он будет прочитан, подправлен, понят и объяснё много раз. Понимание чужого кода гораздо сложнее, чем написание нового с нуля, поэтом инвестировать в понятность кода важно (если, конечно, вы желаете своему коду долго счастливой жизни). Сокращение кода не нужно. Код должен быть понятным, не больше и не меньше. Если вам кажется, что где-то нужно расписать для наглядности — так и сделайте, даж пусть придётся вводить дополнительные переменные только чтобы дать имя промежуточном результату. Если, наоборот, вам кажется, что кода слишком много для той простой штуки которую он делает — вынесите эту штуку в отдельную функцию и придумайте ей правильно название, чтобы пояснить смысл действия. Поддерживайте однородность и общий темп: есл кусок кода запускает космическую ракету в полёт, то кусок кода рядом с ним, которы читает данные из конфигурационного файла, смотрится нелепо. Именование переменных и функций. Не жалейте букв! Байты на винчестере подешевели Вы не должны писать комментарии, чтобы пояснить смысл переменной, иначе читатель долже видеть одно (имя переменной), а в уме держать другое (её смысл). С другой стороны, н надоедайте читателю излишними подробностями. То, что у вас не просто acceptableByteCount а countOfBytesWhichDidNotPassAtLeastTwoFilters, — скучно. Соблюдайте разумный баланс Если вам нужна переменная цикла, назовите её i или j. Придерживайтесь общепринятых соглашений если нужно, придумывайте свои (но разумные!), легко понятные другим. Именуйте переменные правильно. Название должно отображать смысл. Если вы использует одну и ту же переменную в двух разных смыслах, вы делаете неправильно, разделите е на две переменные с однозначным смыслом. Например, не стоит совмещать длину переданно строки и счётчик оставшихся символов для обработки, хотя начальное значение счётчик и совпадает с длиной строки. Старайтесь, чтобы текст читался естественно. Например, имя действия должно бы быт глаголом (не vector.Normalization(), а vector.Normalize() или vector.GetNormal()). Им булевого условия должно быть похоже на условие и скорее всего начинаться с is, has тому подобного. (Например: hasChanges(), isPrime() и т. п.) Ради бога, используйте английски имена, а не русские транслитом! Поверьте, isZarplataComputed() смотрится ужасно. Исключени — языки с кириллическим синтаксисом (1с?) или общепринятый стиль команды. Разделение действий. Да, имеет смысл отделять код в функцию только для того, чтоб правильно назвать этот фрагмент кода. Функции существуют не для повторного использования Функции нужны для логического разбиения кода на части. Если вы видите, что ваша функци ответственна за разные вещи, и вы не можете придумать ей короткого точного названия значит, ваша функция делает чересчур много, и её надо разделить. Часто из супердлинно функции в 500 строк получается десяток классов. И это хорошо. И да, читателю гораздо лучше понять функцию, которая делает одну простую задачу Если функция делает слишком много, у неё кроме более сложного кода более сложные пред и постусловия (а значит, её ещё сложнее понять). Для хорошего разбиения на части проектируйте сверху вниз. Пример: приготовить ед — это что? Решаем, что это значит приготовить французский завтрак. Окей, а что тако приготовить французский завтрак? Это купить круассаны и сварить кофе. А что такое сварит кофе? Это смолоть зёрна в кофемолке, засыпать в турку, добавить воды, поместить на огонь и т. д. Это естественным образом оформляется в процедуры PrepareMeals, PrepareFrenchBreakfast BuyCroissants, MakeCoffee. Ничего выдумывать не пришлось. Уместность комментариев. Старайтесь писать код так, чтобы комментарии не были нужны Очень часто комментарии избыточны; очень часто они устаревают и перестают отображат действительность. Люди часто меняют логику кода, но забывают пробежаться и по комментариям. Не забывайте, что выполняется код, а не комментарии. Поэтому ошибочный, вводящи в заблуждение комментарий (например: /* здесь не может получиться NULL */) гораздо хуж его отсутствия. Если у вас есть кусок кода, снабжённый комментарием, объясняющим, чт он делает, превратите этот код в функцию, а комментарий — в её имя. Полностью избежат комментариев, вероятно, не удастся, но постарайтесь, чтобы комментарии описывали, почем вы делаете так, как делаете, а что именно вы делаете, должно быть понятно из кода. Форматирование. Плохое форматирование очень сильно влияет на читаемость кода. Выработайт стиль и придерживайтесь его. Какой именно стиль вы выберете, в общем-то и не важно главное, чтобы он был логичен и последователен. (Например, если вы ставите пробел посл while, наверное стоит ставить пробел и после if.) Старайтесь, тем не менее, не отступат от общепринятых соглашений (например, имена методов в Java принято выбирать в lowerCamelCase) иначе вам трудно будет читать чужой код. Если вы работаете в команде, не нарушайте общий стиль, даже если вам персональн он не нравится. Если в команде нету общепринятого стиля, предложите его! Расстановк скобок, отступы, пробелы, максимальная длина строк и всё такое важны, чтобы читател не отвлекался. Непоследовательное форматирование сбивает с толку и отвлекает горазд больше, чем это кажется — точно так же, как неправильная пунктуация мешает правильн понимать текст литературного произведения. И последнее. Не заботьтесь о повышении эффективности кода путём понижения его читаемости Выделение отдельного метода — не проблема, современные компиляторы научились inline-ит всё, что нужно. И объединять разные переменные в один регистр они скорее всего умею гораздо лучше вас. Если же в каком-то месте ради низкоуровневой оптимизации действительн нужно ухудшить читаемость, снабдите этот фрагмент достаточными комментариями по повод того, что же происходит в коде, и самое главное — почему такой трюк понадобился.

Ответ 2



Первое, что хотелось бы сказать - это очень хороший вопрос. То, что вы ищете, называется конвенцией написания кода (или стандартами написани кода), и их легко найти по запросу "coding style convention" или "coding standards" Для С / С++ существуют несколько конвенций, какую конкретно вы будете использовать как правило, не имеет значения, главное, чтобы весь проект был выдержан в одном ключе Первыми ссылками выпадают конвенции от гугла (С++) и GNU c Linux Kernel (С) - я их н читал, но они должны в полной мере покрывать вышеописанные вопросы. Что касается комментариев - это довольно спорная позиция, тут придется вырабатыват свою стратегию. Многие считают, что код должен читаться сам по себе без комментариев такие, как я, эту стратегию поддерживают, но считают, что комментарии должны максимальн разжевывать возможное использование (чтобы банально высвечиваться в IDE).

Ответ 3



Я пишу на PHP, Python и Javascript, но все-же позволю себе оставить пару домысло (они касаются твоего 2го пункта). Именно этот пункт доставил моей команде немало хлопот после разрастания проекта. У нас есть внутренний протокол (JSON поверх TCP), с помощью которого компоненты систем общаются друг с другом, назовем его, допустим... TMP-протокол. Есть не один десяток сущностей, которые имею прямое отношение к TMP - всякие интерфейсы гейтвеи, колбэки, "обещания", ожидающие ответ и тд и тп. НИКОГДА нельзя давать названия классам и переменным, которые не дают примерного поняти о своем предназначении, например: class TmpProtocol Protocol в данном случае - это лишние 8 символов (tmp - это и так протокол), названи класса не говорит вообще ни о чем. Сравните с этим: class TmpClientGateway Лучше? Намного! Интуитивно хочется сделать что-то вроде этого: $a = new TmpClientGateway(); $a->makeRequest(...) Теперь по поводу переменных. Если переменная имеет хоть какое-то значение во внешнем мире, то и ей нужно дават осмысленное название, например следующий код вскружит голову и доведет вас до тошноты: self.deferred = defer.Deferred() Мы пообещали кому-то (не важно кому) отложенный результат. Но вот, что мы пообещал - никому не понятно (и вы сами забудете через год). Куда лучше написать что-нибудь таком духе: self.serverResponse = defer.Deferred() Нужно себе отдавать отчет в том, что эта конкретная штука делает и называть ее соответствующи образом. И мешанина из классов, обслуживающих tmp: class tmpProtocol, class Handler, class tmpInterface превращается в что-то более понятное: class tmpServerRequest, class tmpServerRequestFactory, class tmpMethodDecorator И еще, если некий класс - наследник от какого-то стандартного Factory, то и переменны этого нового класса в названии должны содержать Factory, а не, скажем, Handler Теперь насчет 3го пункта: Не заставляйте один и тот же кусок кода обрабатывать ошибку tcp-соединения и ошибку скажем, "нецелостности" пришедших данных (даже если сверху, для пользователя, эти ситуаци выглядят одинаково). Это сделает код абсолютно непрозрачным. Гораздо лучше разнести функционал по двум пусть даже и почти одинаковым, функциям и избежать непонятных ветвлений из if-else-elsif-elsif. Особенно сводит с ума, когда в теле els`ов происходит нечто почти одинаковое, н отличающееся, на 1 строчку (в одном елсе - вручную закрыли, сокет, а в другом - не стал этого делать). Будет намного понятнее, если первую ситуацию обработает функция errCorruptedDat (данные пришли, но кривые, поэтому сокет закроем!) , a вторую ситуацию - errNoRouteToHos (сокет и так не открылся). Прошу прощения за вырожденные примеры.

Ответ 4



Качество вашего С кода в основном зависит от вашего же практического опыта и степен просветеления. Кроме этого в каждом крупном проекте свои причуды по поводу форматирования. Поэтому отвечу по пунктам вопроса, воспользовавшись негласной(уже нет) конвенцией что я обычно использую когда пишу C код. Two or more use a for(c). Сокращаю только в том случае если с помощью этого можн автоматизировать весь процесс. Никогда не допускаю китайского кода. Всегда использую длинные и понятные идентификаторы в нижнем регистре разделенны _ из которых сразу ясен контекст и вся дополнительная информация. Никогда не сокраща их. very_long_clear_and_useful_variable_name. Никогда не использую венгерскую нотаци с информацией о типе в идентификаторе. Создаю столько наиболее подходящих абстракций сколько нужно для решения задачи, н больше.Также по возможности следую жесткому эмпирическому правилу гласящему что: Не автоматически сгенерированная функция в которой есть либо строки длиннее 80 символов либо больше 3 уровней вложенности инструкций потока управления, либо больше 3 вложенны скобочных пар в одной строке, либо больше 40 строк, либо получающая больше 3 параметров(variadi считается за 1), либо в коде которой есть больше 0 явно написанных чисел или строковы констант с вероятностью близкой к 100% никому не нужна во внешнем мире и сгодится тольк в качестве учебного примера или для аккуратного внутреннего пользования. Каждый раз когда вы вставляете в продакшн фукнцию, которая не удоволетворяет правил одна звезда на небе гаснет, толпа школьников садистов заживо препарирует хомячка, в мозгу ваших коллег читающих её умирают нейроны. Вообще не использую комментарии в определениях, вместо них делаю принудительную выгрузк в дебаг лог. В объявлениях вставляю только шапку и краткое описание того что делае этот файл. МАКРОСЫ большими буквами, все остальное маленькими через _. Использую K&R отсупы DeprecatedCamelCaseIdentifiers не использую. Использую суффикс _t, чтобы отличать, объявленны через typedef структуры от всего остального. Хотя конечно сколько конвенций не применяй С код вообще довольно сложно сделать легкочитаемым. В подтверждении этого можно посмотреть международный конкурс самых запутанных програм на C. Вот, например, типичная программа оттуда, которая просто рисует огромный смайлик показывающий язык, в терминале: m(f,a,s)char*s; {char c;return f&1?a!=*s++?m(f,a,s):s[11]:f&2?a!=*s++?1+m(f,a,s):1:f&4?a--? putchar(*s),m(f,a,s):a:f&8?*s?m(8,32,(c=m(1,*s++,"Arjan Kenter. \no$../.\""), m(4,m(2,*s++,"POCnWAUvBVxRsoqatKJurgXYyDQbzhLwkNjdMTGeIScHFmpliZEf"),&c),s)): 65:(m(8,34,"rgeQjPruaOnDaPeWrAaPnPrCnOrPaPnPjPrCaPrPnPrPaOrvaPndeOrAnOrPnOrP\ nOaPnPjPaOrPnPrPnPrPtPnPrAaPnBrnnsrnnBaPeOrCnPrOnCaPnOaPnPjPtPnAaPnPrPnPrCaPn\ BrAnxrAnVePrCnBjPrOnvrCnxrAnxrAnsrOnvjPrOnUrOnornnsrnnorOtCnCjPrCtPnCrnnirWtP\ nCjPrCaPnOtPrCnErAnOjPrOnvtPnnrCnNrnnRePjPrPtnrUnnrntPnbtPrAaPnCrnnOrPjPrRtPn\ CaPrWtCnKtPnOtPrBnCjPronCaPrVtPnOtOnAtnrxaPnCjPrqnnaPrtaOrsaPnCtPjPratPnnaPrA\ aPnAaPtPnnaPrvaPnnjPrKtPnWaOrWtOnnaPnWaPrCaPnntOjPrrtOnWanrOtPnCaPnBtCjPrYtOn\ UaOrPnVjPrwtnnxjPrMnBjPrTnUjP"),0);} main(){return m(0,75,"mIWltouQJGsBniKYvTxODAfbUcFzSpMwNCHEgrdLaPkyVRjXeqZh");} Она вполне рабочая. Какая уж тут конвенция. P.S. Чтобы немного облегчить понимание сложных объявлений вроде такого: char **(*(*(*x)[100])(int,char*,double ***,void(*)(int**,char[])))[50]; На самом деле тут все просто и понятно. x это просто указатель на массив из 10 указателей на функцию принимающую аргументы (int, указатель на char, указатель на указател на указатель на double, указатель на функцию принимающую (указатель на указатель н int, массив char) возвращающую void) возвращающую указатель на массив из 50 указтеле на указателей на char можно воспользоваться их переводчиком на английский

Ответ 5



Прежде всего нужно сказать, что ответа на этот вопрос нет. На обе его части... Понятие красоты вообще нерелевантно коду. Код не может быть красивым. Это не стихи и не проза. И он не должен быть красивым. Его задача состоит не в том, чтобы доставлят кому-то эстетическое удовольствие, а в том, чтобы компилироваться. У него сугубо инструментальна функция. Наверняка, бывают люди, которым разнообразные конструкции циклов и условны операторов нравятся чисто эстетически, но это скорее перверсия... не нужно ориентироватьс на таких людей. Хотя нужно отметить, что красивым может быть алгоритм, который реализова в коде. Но надо эти вещи чётко разделять. Назвать какой-то код красивым - это всё равно что назвать красивым железобетон, из которого построено красивое здание. Что же касается читаемости кода, то с этим дело обстоит получше. Хотя и на эту част вопроса ответа тоже нет. В индустрии широко распространено ошибочное мнение, будто б читаемость - это свойство самого кода... будто бы коду можно придать такую форму, котора сделает его читаемым. В действительности это не так. Код не может быть читаемым са по себе... отдельно от того, кто его читает. Это более-менее очевидная мысль. Но, сожалению, мало кто об этом задумывается. На самом деле, нужно думать о читаемости код не как о свойстве самого кода, а как об отношении между двумя и более людьми, которо каким-то неуловимым образом встроено в тот код, который они пишут и читают. Если у каждог из этих людей получается писать код так, что другие могут читать и понимать его более-мене комфортно, то значит эти люди пишут читаемый код. Но эта читаемость неразрывно связан с этими конкретными людьми. Нельзя передать код другим людям, сохранив при этом ег читаемость на прежнем уровне. У других людей в мозгу будут уже сформированы совсем други паттерны, связанные с кодом, и потому читаемость любого кода, который в них не вписывается обязательно просядет. Пресловутые Coding Style Guides в действительности подходят к решению проблемы именн со стороны людей. Их задача состоит лишь в том, чтобы зафиксировать некий набор разумны правил, которых люди, работающие вместе, соглашаются придерживаться. Не потому, чт эти правила чем-то объективно хороши, а просто потому, что конкретно им такой набо правил наиболее удобен в качестве общего. В пункте 4 очень точно схвачена суть проблемы, хотя речь там идёт о комментариях "Свой код всегда понятен." - Эту фразу нужно мысленно повторять три раза всякий раз когда возникает желание вынести какое-либо суждение о своём собственном коде. В то числе и о его читаемости. Ну, или можно слегка изменить фразу: "Свой код всегда читаем." В общем, вне всякой связи с людьми коду можно придать лишь такие свойства как правильность компилируемость, эффективность и т.д. Свойство же читаемости существует в коде в форм чего-то эфемерного, что связывает этот код с какими-то конкретными людьми. И чтобы оценит код на читаемость, нужно показать его другим людям. Причём не просто другим случайны людям, а именно тем, у которых есть личная заинтересованность в том, чтобы его читат и понимать. Другого способа нет. Если же код интересен только самому автору, и он са может его комфортно читать, то значит код уже читаем на 100%. Ничего больше делать н нужно. Повысить читаемость выше 100% нельзя.

Ответ 6



К каждому языку - свой подход. Для тех же C и C++ ответ на некоторые пункты може быть совершенно разным. Сокращение количества кода иногда бывает плюсом, т.к. рыться в колоссальном codebas часто неприятно, а мерянье количеством KLoC в своих проектах - дурацкое занятие. Н надо не переборщить. У нас тут, знаете ли, не code-golf =) код всегда должен быть читаемым даже для человека, видящего его в первый раз! Именование переменных. Это дело вкуса, но важно, чтобы имя переменной предоставлял хоть какую-нибудь информацию о том, что она такое есть. ИМХО самый важный пункт, здесь распишу (немного побольше, чем спрашивалось, ну д ладно) с конкретикой для С, т.к. имею с ним некоторый опыт. Что-то из этого применим к другим языкам. Заранее предупреждаю, все далее - чисто мое ИМХО. В любом C-коде главное - баланс. Важно соблюдать баланс между стремлением сделать код модульнее и реюзабельнее, добавля в него больше специализированных функций, и созданием слишком длинных, неоптимальны и уж точно нечитаемых цепочек вызовов функций (инлайнить умеют далеко не все C-компиляторы а стэк не резиновый, и фреймы не моментально создаются). Баланс должен быть между тем, что берет на себя ваше API, и тем, что оно взваливае на пользователя (вызывающий API код). Например, есть негласное правило - если API инициализируе только что созданный объект, аллокацию памяти под этот объект надо оставить пользователю. Баланс должен быть между количеством функций, globals-ов, прототипов функций и макросо в одном файле (и в одном translation unit-е). С одной стороны, сильно набивать ни файл ни translation unit нехорошо, но с другой стороны, и создавать отдельный файл для одно функции неоправданно. И, конечно же, баланс должен быть между тем, что кому и где видно. Если кто вам скажет что в C нет энкапусляции, не верьте, она там была задолго до C++ и его модификатор private! =) Чтобы энкапуслировать функцию или global, объявите ее статической (static в отдельном translation-unit-е, тогда к ней можно будет получить доступ только из нег же. Чтобы энкапуслировать членов структуры, используйте ее как opaque pointer - эт можно сделать, например, объявив ее как incomplete type в коде, вызывающем энкапсулирующе API, а определить ее уже в самом API (хороший пример тут). Комментарии - это хорошо. Но нельзя на них слишком сильно полагаться. Если код плох написан, то тут никакие комментарии не спасут. Опять же, нужен баланс - комментарие не должно быть мало (за исключением очень редких случаев, когда код благодаря красноречивы именам функций/переменных и т.д. и логичного построения алгоритмов читаем сам по себе) но и не должно быть много (как в поговорке: 90% комментариев, 10% кода, но все равн нихрена не понимаю, что этот код делает). Стиль - это лично ваше дело. Конечно, у некоторых языков есть идиоматический стиль которого стараются все придерживаться (например, C# с майкрософтовским стилем, или Jav со стилем примеров из Javadoc). Проблема в том, что у C их что собак нерезанных. Кто-т пишет код, как в примерах в книге K&R, кто-то следует формату Linux Kernel - а, кто-т предпочитает формат Столлмана... Вот здесь энное количество примеров кода разных стилей Вообще, стиль себе каждый программист должен выбрать сам (лично я, например, даже н C пишу на чем-то сродни стилю Javadoc-а, с camelCase-ом и индентацией, похожей на BS KNF). И, конечно, на каждом себя уважающем предприятии есть свой, иногда уникальный style-guide, определяющий, КАК должен выглядеть код, так что надо уметь адаптироватьс к другим стилям.

Ответ 7



Буду отвечать общими принципами - они сами подходят к Си++, но примеры буду приводит те, которые приходят в голову, не обязательно на плюсах. Код должен быть кратким. Но не максимально. Например, я как-то переписал несколько экранов разметки на несколько строк (html AngularJS). И добавил комментарий, описывающий, что там вообще происходит. А вот пример на VB.NET, когда сокращение кода - это жесть: X *= 10 - 5 значащих символов X &= 0 - 4 значащих символа и жуткий оверхед при выполнении: сначала мы конвертируе числа X и 0 в строки, потом создаём новую строку выполнив конкатенацию, потом парси получившуюся строку обратно в число и выполняем присваивание. Место такому коду - тольк в codegolf-задачках, больше нигде. В чрезмерно ужатом коде разобраться может быть очень сложно, а уж на Си++ - особенно. На мой взгляд, имена переменных должны быть краткими. Но при этом осмысленными. без излишних сокращений. Да, я могу понять, что такое s2e в Switch to English но на мой взгляд, такие сокращения оправданы только для частоиспользуемых вещей, а остальных случаях их применять не следует. И я не люблю распространённые сокращени tmp и cnt - эти 1 - 2 символа не стоят того. Всё по ситуации. Если есть осмысленный блок, который хочется вынести в функцию то да. Если нет, то не надо. Если вынесение вызывает проблемы, то тоже не надо. Ка вариант - написать комментарий, что делает конкретный участок кода и поставить обрамляющи этот участок фигурные скобки, чтобы блок был выделен явно:// Сделать что-то   {   ТутКакойТоДлинныйКод();   } Чрезмерное выделение функций на каждый чих мне не нравится. Да, некоторые любят когда код можно читать как текст, но код обычно читают не чтобы полюбоваться, а чтоб что-то в нём изменить. И искать нужное место, когда перед тобой почти текст, а не ко мне очень неудобно. Комментарии должны говорить об идее кода или пояснять какие-то сложные моменты. Пояснят то, что можно понять из кода, обычно не стоит. Единственное исключение, это когда ко делает что-то совсем неочевидное. Имеет смысл пояснять какие-то подводные камни и ограничения а так же высокоуровневые описания. Имеет смысл отмечать комментарием то, что при перво взгляде кажется ошибкой. Например, присваивания в условиях и отсутствие break в switch'е. Про заглавные буквы комментировать не буду. Что касается отступов - почти всегда пропускаю строку перед и после блоками. Предпочитаю не ставить фигурные скобки: https://ru.stackoverflow.com/a/424351/178988. Не пишу несколько операторов в одной строке просто так. Допускаю возможность использования запятой. Если есть основания выровнять похожие строки столбцами - делаю это. Это единственны случай помещения нескольких операторов в строку.

Комментариев нет:

Отправить комментарий