Это принцип стиля кодирования - например, принцип единого выхода
Люди, которые все еще обращают внимание на один выход или несколько выходов, все еще застряли в конце 1960-х годов. В то время такое обсуждение было важным, так как мы были в зачаточном состоянии структурированного программиста, и было довольно много лагерей, провозглашавших, что выводы, лежащие в основе теоремы Бома-Якопини о структурированных программах, не были универсально применимы ко всем конструкциям программирования.
Это то, что должно было быть решено давно. Ну, это было решено (почти 4 десятилетия, если быть точным, как в академических кругах, так и в отрасли), но люди (те, кто абсолютно за или против) не обращали внимания.
Что касается остальных моих ответов, все относительно (что не в программном обеспечении?):
- действительно хорошая вещь?
Да. Большую часть времени для общего случая, с оговорками, характерными для пограничных случаев и языковых конструкций программирования.
Всегда или просто иногда?
Большую часть времени.
Насколько это действительно важно?
Зависит.
Читаемый код против нечитаемого кода. Увеличенная сложность (которую мы должны знать, теперь увеличивает вероятность появления ошибок) по сравнению с более простой сложностью (и, следовательно, меньшей вероятностью ошибок). Языки, компиляторы которых не добавляют неявный возврат (скажем, Pascal, Java или C #) и те, которые по умолчанию int (C и C ++).
В конце концов, это навык, отточенный в человеко-часах за клавиатурой. Иногда нормально иметь несколько операторов return, как здесь (в некотором псевдокоде Pascal'esque):
function foo() : someType
begin
if( test1 == true )
then
return x;
end
doSomethignElseThatShouldnHappenIfTest1IsTrue();
return somethingElse();
end;
Цель ясна, а алгоритм достаточно мал и не сложен, так что он не гарантирует создание переменной 'flag', которая содержит возможное возвращаемое значение, используемое в одной точке возврата. Алгоритм может быть ошибочным, но его структура достаточно проста, поэтому усилия по обнаружению ошибки (скорее всего) незначительны.
Иногда это не так (здесь используется C-подобный псевдокод):
switch(someVal)
{
case v1 : return x1;
case v2 : return x2:
case v3 : doSomething(); // fall-through
case v4: // fall-through
case v5: // fall-through
case v6: return someXthingie;
...
...
default:
doSomething(); // no return statement yet
}
Здесь алгоритм не имеет простой структуры, и оператор switch (в стиле C) допускает переходные этапы, которые могут выполняться или не выполняться преднамеренно как часть алгоритма.
Возможно, алгоритм правильный, но плохо написан.
Или, может быть, внешними силами, выходящими за пределы возможностей программиста, это фактическое (и правильное) представление законно необходимого алгоритма.
Может быть, это неправильно.
Чтобы раскрыть правду обо всем этом, требуется гораздо больше усилий, чем в предыдущем примере. И в этом заключается то, во что я твердо верю (учтите, что у меня нет формальных исследований, подтверждающих это):
Предполагая, что фрагмент кода считается правильным:
Многократные операторы возврата увеличивают читаемость и простоту такого фрагмента кода, если фрагмент представляет собой простой алгоритм с изначально простой структурой потока. Под простым я не имею в виду маленькое, но я имею в виду понятное по сути или самоочевидное , то, что не требует непропорциональных усилий по чтению (и не побуждает людей рвать, проклинать чью-то мать или глотать пулю, когда им приходится ее читать. )
Один оператор возврата повышает удобочитаемость и простоту такого фрагмента кода, если возвращаемое значение вычисляется либо во время выполнения алгоритма, либо если этапы алгоритма, ответственные за его вычисление, могут быть сгруппированы в одном месте в структуре алгоритма. ,
Один оператор возврата снижает удобочитаемость и простоту такого фрагмента кода, если он требует присваиваний одной или нескольким флаговым переменным, при этом местоположения таких присваиваний не расположены равномерно по всему алгоритму.
Множественные операторы возврата уменьшают удобочитаемость и простоту такого фрагмента кода, если операторы возврата не распределены равномерно по алгоритму и если они разграничивают взаимоисключающие блоки кода, которые не являются однородными по размеру или структуре между собой.
Это тесно связано со сложностью рассматриваемого фрагмента кода. А это, в свою очередь, связано с мерами цикломатической сложности и сложности Холстеда. Из этого можно наблюдать следующее:
Чем больше размер подпрограммы или функции, тем больше и сложнее ее структура потока внутреннего контроля, и тем выше вероятность того, что вы столкнетесь с вопросом, использовать ли несколько или одиночные операторы возврата.
Вывод таков: сохраняйте свои функции небольшими, выполняя одно и только одно действие (и делая это хорошо). Если они демонстрируют номинально малые показатели цикломатической сложности и сложности Холстеда, они не только должны быть, скорее всего, правильными и выполнять понятные задачи, но их внутренние структуры также будут относительно самоочевидными.
Тогда, и только тогда вы можете довольно легко и не теряя много сна, вы можете решить, следует ли использовать один и несколько возвратов, не рискуя при этом ошибиться с любым из вариантов.
Можно также взглянуть на все это и предположить, что, когда люди борются с проблемой единичного или множественного возврата, это происходит потому, что - из-за неопытности, глупости или отсутствия трудовой этики - они не пишут чистый код и имеют тенденцию писать чудовищные функции с полным игнорированием цикломатических и холстедских мер.