Подтвердить что ты не робот

Почему функция должна иметь только одну точку выхода?

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

Я думал, что это связано с CS, но этот вопрос был сбит в cstheory stackexchange.

4b9b3361

Ответ 1

Существуют разные школы мысли, и это в значительной степени сводится к личным предпочтениям.

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

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

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

Я прямо в среднем лагере. Обеспечение единственной точки выхода является бессмысленным или даже контрпродуктивным ограничением ИМХО, в то время как случайное исключение во всем методе может иногда приводить к беспорядочным трудностям в логике, когда становится трудно увидеть, будет ли данный бит кода или не будет казнены. Но "строгая" ваш метод позволяет значительно упростить тело метода.

Ответ 2

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

  if (!argument)  // Check if non-null
    return ERR_NULL_ARGUMENT;
  ... process non-null argument
  if (ok)
    return 0;
  else
    return ERR_NOT_OK;

clearer чем:

  int return_value;
  if (argument) // Non-null
  {
    .. process non-null argument
    .. set result appropriately
  }
  else
    result = ERR_NULL_ARGUMENT;
  return result;

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

Ответ 3

Если вам кажется, что вам нужно несколько точек выхода в функции, функция слишком велика и делает слишком много.

Я бы рекомендовал прочитать главу о функциях в книге Роберта К. Мартина "Чистый код".

По существу, вы должны попытаться написать функции с 4 строками кода или меньше.

Некоторые заметки из Блог Майка Лонга:

  • Первое правило функций: они должны быть маленькими
  • Второе правило функций: они должны быть меньше, чем
  • Блокирует внутри операторов if, в то время как операторы, для циклов и т.д. должны быть длиной в одну строку
  • ... и эта строка кода обычно называется вызовом функции
  • Должно быть не более одного или двух уровней отступов
  • Функции должны делать одно.
  • Операторы функций должны быть на одном уровне абстракции
  • Функция должна содержать не более трех аргументов
  • Выходные аргументы - это запах кода
  • Передача логического флага в функцию действительно ужасна. Вы по определению выполняете два действия в функции.
  • Побочные эффекты - это ложь.

Ответ 4

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

Ответ 5

С большинством всего, это сводится к потребностям поставляемого. В "старые времена" код спагетти с несколькими точками возврата вызывал утечки памяти, поскольку кодеры, которые предпочитали этот метод, обычно не хорошо очищались. Также возникали проблемы с некоторыми компиляторами, "теряющими" ссылку на возвращаемую переменную, поскольку стек был выбит во время возврата, в случае возврата из вложенной области. Более общая проблема заключалась в одном из кода повторного входа, который пытается иметь состояние вызова функции точно так же, как и его возвращаемое состояние. Мутаторы oop нарушили это, и концепция была отложена.

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

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

- 2 цента

Подробнее см. в этом документе: NISTIR 5459

Ответ 6

На мой взгляд, совет по выходу функции (или другой структуры управления) только в одной точке часто перепродан. Обычно приводятся две причины для выхода только в одной точке:

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

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

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

Удачи.

Ответ 7

Я был сторонником стиля с одним выходом. Мои рассуждения пришли в основном от боли...

Одиночный выход легче отлаживать.

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

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

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

Ответ 8

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

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

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