Я часто писал такого рода функции в обоих форматах, и мне было интересно, если один формат предпочтительнее другого и почему.
public void SomeFunction(bool someCondition)
{
if (someCondition)
{
// Do Something
}
}
или же
public void SomeFunction(bool someCondition)
{
if (!someCondition)
return;
// Do Something
}
Я обычно кодирую с первым, потому что так работает мой мозг во время кодирования, хотя я думаю, что предпочитаю второй, так как он сразу же заботится о любой обработке ошибок, и мне легче читать
Ответы:
Я предпочитаю второй стиль. Сначала удалите недопустимые случаи, либо просто выйдите, либо вызвав исключения в зависимости от ситуации, вставьте пустую строку, затем добавьте «реальное» тело метода. Мне легче читать.
источник
Определенно последнее. Первый не выглядит плохо сейчас, но когда вы получаете более сложный код, я не могу себе представить, что кто-то подумает так:
более читабельно, чем
Я полностью признаю, что никогда не понимал преимущества единых точек выхода.
источник
return value;
помогает!?! Затем нужно охотиться на полдюжиныvalue = ...
, с тем недостатком, что вы никогда не уверены, что значение не изменится между этим заданием и окончательным возвратом. По крайней мере, немедленное возвращение ясно, что результат больше ничего не изменит.Это зависит - в общем, я не собираюсь изо всех сил пытаться переместить кучу кода, чтобы выйти из функции раньше - компилятор, как правило, позаботится об этом за меня. Тем не менее, если наверху есть какие-то базовые параметры, которые мне нужны, и я не могу продолжить, я прорвусь рано. Точно так же, если условие генерирует гигантский
if
блок в функции, у меня также будет ранний прорыв в результате этого.Тем не менее, если функция требует некоторых данных при вызове, я обычно собираюсь выдавать исключение (см. Пример), а не просто возвращать.
источник
Я предпочитаю раннее возвращение.
Если у вас есть одна точка входа и одна точка выхода, то вы всегда должны отслеживать весь код в своей голове вплоть до точки выхода (вы никогда не узнаете, делает ли какой-то другой фрагмент кода ниже что-то еще с результатом, поэтому вы надо отследить, пока не появятся). Вы делаете это независимо от того, какая ветвь определяет конечный результат. Это трудно понять.
Если существует одна запись и существует несколько, вы вернетесь, когда получите свой результат, и не потрудитесь отслеживать его до конца, чтобы убедиться, что никто не сделает с ним ничего другого (потому что больше ничего не будет с тех пор, как вы вернулись). Это похоже на разделение тела метода на несколько шагов, каждый шаг с возможностью вернуть результат или позволить следующему шагу испытать свою удачу.
источник
В программировании на Си, где вы должны выполнять очистку вручную, многое можно сказать о возврате из одной точки. Даже если сейчас нет необходимости что-то очищать, кто-то может отредактировать вашу функцию, выделить что-то и нужно очистить ее перед возвратом. Если это произойдет, это будет кошмарная работа, просматривая все обратные операторы.
В программировании на C ++ у вас есть деструкторы и даже теперь охранники выхода из области видимости. Все это должно быть здесь, чтобы гарантировать, что код в первую очередь безопасен для исключений, поэтому код хорошо защищен от преждевременного выхода и, следовательно, это не имеет логического недостатка и является чисто стилевой проблемой.
Я недостаточно осведомлен о Java, будет ли вызываться блочный код finally, и смогут ли финализаторы справиться с ситуацией, когда нужно что-то гарантировать.
C # Я, конечно, не могу ответить на.
D-язык дает вам надлежащие встроенные средства защиты при выходе из области видимости и поэтому хорошо подготовлен к досрочному выходу и поэтому не должен представлять проблему, кроме стиля.
Во-первых, функции, конечно, не должны быть такими длинными, и, если у вас огромный оператор switch, ваш код, вероятно, также будет плохо обработан.
источник
goto
и, возможно, двухточечный возврат. Пример (форматирование кода в комментариях невозможно):foo() { init(); if (bad) goto err; bar(); if (bad) goto err; baz(); return 0; err: cleanup(); return 1; }
Раннее возвращение к победе. Они могут показаться уродливыми, но гораздо менее уродливыми, чем большие
if
обертки, особенно если нужно проверить несколько условий.источник
Я использую оба.
Если
DoSomething
3-5 строк кода, то код выглядит красиво, используя первый метод форматирования.Но если в нем много строк, я предпочитаю второй формат. Мне не нравится, когда открывающие и закрывающие скобки не на одном экране.
источник
Классическая причина единственного входа-единственного выхода состоит в том, что в противном случае формальная семантика становится невыразимо уродливой в противном случае (та же самая причина, по которой GOTO считался вредным).
Иными словами, легче предположить, когда ваше программное обеспечение выйдет из процедуры, если у вас есть только 1 возврат. Что также является аргументом против исключений.
Обычно я минимизирую подход с ранним возвратом.
источник
Лично я предпочитаю проверять условия прохождения / провала в начале. Это позволяет мне сгруппировать большинство наиболее распространенных сбоев в верхней части функции с остальной логикой, которой необходимо следовать.
источник
По-разному.
Ранний возврат, если есть некоторое очевидное тупиковое условие, которое нужно проверить сразу, что сделает бессмысленным запуск остальной части функции. *
Установите Retval + single return, если функция более сложна и может иметь несколько точек выхода в противном случае (проблема читабельности).
* Это часто может указывать на проблему с дизайном. Если вы обнаружите, что многим вашим методам необходимо проверить какое-либо внешнее состояние / состояние параметра перед тем, как запускать остальную часть кода, это, вероятно, должно быть обработано вызывающей стороной.
источник
Fred
окна уже установленаFred
, а установка имени элемента управления в его текущее состояние приведет к перерисовке (что, хотя в некоторых случаях потенциально полезно, может привести к надоедать одному), было бы разумно иметь метод set-name для досрочного выхода, если старые и новые имена совпадают.Используйте If
В книге Дона Кнута о GOTO я читал, как он объясняет причину, по которой наиболее вероятное условие стоит первым в утверждении if. При условии, что это все еще разумная идея (а не исключение из соображений скорости эпохи). Я бы сказал, что ранние возвраты не являются хорошей практикой программирования, особенно если учесть тот факт, что они чаще всего используются для обработки ошибок, если ваш код с большей вероятностью не сработает, чем не сработает :-)
Если вы последуете приведенному выше совету, вам нужно будет поместить это возвращение в конец функции, а затем вы можете даже не называть его возвратом, просто установить код ошибки и вернуть его через две строки. Тем самым достигая идеала 1 вход 1 выход.
Delphi Specific ...
Я считаю, что это хорошая практика программирования для программистов на Delphi, хотя у меня нет никаких доказательств. Pre-D2009, мы не имеем атомный способ вернуть значение, у нас есть
exit;
иresult := foo;
или мы могли бы просто выбросить исключение.Если бы вам пришлось заменить
за
Вы можете просто устать от того, что видите это на вершине каждой из ваших функций и предпочитаете
и просто избегать
exit
вообще.источник
if true then Exit(foo);
Я использую часто метод для первой инициализацииresult
доnil
илиFALSE
соответственно, а затем проверить все условия ошибки и толькоExit;
если один удовлетворяются. Случай успехаresult
(обычно) устанавливается где-то в конце метода.Я согласен со следующим утверждением:
Взято из этого вопроса в stackoverflow .
источник
Я использую ранний возврат почти исключительно в эти дни, до крайности. Я пишу это
как
но это действительно не имеет значения. Если у вас есть более одного или двух уровней вложенности в ваших функциях, их необходимо отключить.
источник
Я бы предпочел написать:
источник
DoSomeFunctionIfSomeCondition
?Как и вы, я обычно пишу первый, но предпочитаю последний. Если у меня много вложенных проверок, я обычно рефакторинг ко второму методу.
Мне не нравится, как обработка ошибок удалена от проверки.
Я предпочитаю это:
источник
Условия наверху называются «предварительными условиями». Ставя
if(!precond) return;
, вы визуально перечисляете все предпосылки.Использование большого блока if-else может увеличить накладные расходы на отступ (я забыл цитату о трехуровневых отступах).
источник
Я предпочитаю сохранить, если заявления небольшие.
Итак, выбирая между:
а также
Я бы выбрал то, что вы описали как «раннее возвращение».
Имейте в виду, я не забочусь о досрочном возврате или о чем-то другом, я просто очень хотел бы упростить код, сократить тела операторов if и т. Д.
Вложенные, если и для, и в то время как ужасны , избегайте их любой ценой.
источник
Как говорят другие, это зависит. Для маленьких функций, которые возвращают значения, я могу закодировать ранние результаты. Но для значительных функций мне нравится всегда иметь место в коде, где я знаю, что я могу поместить что-то, что будет выполнено до его возвращения.
источник
Я практикую безотказно на функциональном уровне. Он сохраняет код непротиворечивым и чистым (для меня и тех, с кем я работал). Из-за этого я всегда возвращаюсь рано.
Для некоторых часто проверяемых условий вы можете реализовать аспекты для этих проверок, если используете AOP.
источник