Что такое пользовательский возврат

Обновлено: 28.06.2024

Рассмотрим ситуации использования операторов перехода Перейти (GoTo), Возврат (Return), Прервать (Break), Продолжить (Continue). Как вы считаете - это дурной тон, нормальная практика или зависит от ситуации?

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

И действительно Дональд Кнут в свое время писал:

Давайте рассмотрим примеры использования и не использования этих операторов и сравним.

1. Оператор Перейти (GoTo).


2. Оператор Возврат (Return).

Давайте рассмотрим некоторый виртуальный пример. Задача будет следующая: Требуется написать функцию получения математическое ожидание покупок клиента или средний чек.

Какие выводы мы можем сделать из двух вышеуказанных примеров?

3. Оператор Прервать (Break)


Один из самых востребованных операторов, если рассмотреть программирование на C++. В свое время я часто его использовал в связке с Switch и Операторах цикла (For, While). Обратите внимание, что оператор "Прервать" может использоваться и для выхода из бесконечного цикла.
Рассмотрим вариацию типового примера для подключения к клиенту тестирования механизма автоматизированного тестирования от 1С.

Какие отличия мы видим?

  • в первом случае мы последовательно встречаемся с условиями, так проводить анализ значительно проще на мой взгляд
  • во втором случае код внутри процедуры получился значительно меньше и сразу видно условие выхода из цикла
  • Использование "вечных" условий в операторах цикла - это дурной тон для языка 1С Предприятие.

4. Оператор Продолжить (Continue)

Оператор "Продолжить" (continue) позволяет сразу перейти в конец тела цикла, пропуская весь код, который находится под ним. Это полезно в тех случаях, когда мы хотим завершить текущую итерацию раньше времени.

Будьте осторожны при использовании оператора "Продолжить" с циклом "Пока" (while). Поскольку в этих циклах инкремент счетчиков выполняется непосредственно в теле цикла, то использование "Продолжить" может привести к тому, что цикл станет бесконечным!

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

В таблице хранится наименование контрагента и некоторые дополнительные данные (сумма и т.п.). В рамках обработки будем искать ссылку на контрагента в базе данных, если данные битые, то будем пропускать поиск.

Процедура "НайтиСсылкуПоНаименованию" ищет ссылку контрагента в базе 1С.

Функция "ЭтоБитыеДанные" проверяет наличие "кривой" информации в полях Сумма, КонтрагентНаименование.

Как видно, то в результате необдуманного выбора оператора цикла, установки счетчика и размещения условия прервать, мы уйдем в бесконечный цикл. Лучше переписать так:

Теперь рассмотрим вариант без использования оператора "Продолжить".

  • В первом случае мы легко можем допустить ошибку, которая приведет к бесконечному циклу (эта ошибка будет "плавающая", т.е. не всегда будет срабатывать). Поэтому лучше выбрать другой оператор цикла.
  • Большой код, рекомендуем выносить рефакторингом.
  • Второй вариант выглядит более логически понятным и "завершенным".

5. Операторы прервать и продолжить

Многие учебники рекомендуют не использовать операторы "Прервать" (break) и "Продолжить" (continue), поскольку они приводят к произвольному перемещению точки выполнения программы по всему коду, что усложняет понимание и следование логике выполнения такого кода.

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

Функция "ЭтоБитыеДанные" проверяет наличие "кривой" информации в полях Сумма, Контрагент.

Код выше требует рефакторинга, т.к. гонять цикл впустую (вдруг битые данные будут сразу со второго элемента) - это "жесть" конечно. Иными словами для следования структурному подходу требуется изменение структуры.

Рассмотрим результат сравнения:

  • Не желание использовать операторы переходов вынудило нас во втором случае полностью переписать код
  • Во втором случае потребовалось заводить лишние переменные
  • Во втором случае потребовалось вынести часть логики из цикла в конец функции, что увеличивает объем кода выполняющий решения поставленной задачи
  • В циклах "Для" и "Для каждого" удобно использовать оператор "Продолжить" для быстрого перехода к следующей итерации по результатам условий, если текущая строка не требует обработки.

Заключение

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

  • Операторы " Продолжить " и " Прервать " удобно использовать в циклах " Для " и " Для каждого "
  • Если речь идет про оператор цикла " Пока ", то тут лучше стараться не использовать " Продолжить ", т.к. в некоторых комбинациях возможно создание бесконечного цикла.
  • Дурной тон в операторах циклов использовать "вечные" условия по типу " Пока Истина Цикл".
  • При использовании оператора " Возврат " надо следить, чтобы не оставалось недостижимого кода.
  • Также возможны случаи написания недостижимого кода с операторами " Продолжить " и " Прервать ".
  • Оператор " Возврат " удобно использовать в начале функций при выполнении проверок на консистентность (корректность) входных параметров.
  • Оператор " Перейти " запрещено использовать.
  • Если придерживаться структурного подхода, то следует себя ограничивать в создании вложенности (или "матрешек") с условиями " Если Тогда ", так как это затрудняет понимание кода и увеличивает критерий цикломатичности.
  • В процессе разработки (кодирования) всегда выполняем рефакторинг кода и выносим большие блоки в отдельные функции.
  • Используйте в процессе работы анализ качества кода (код-ревью) (По следам код-ревью, Как завести у себя в команде код-ревью. Отвечаем на вопросы)
  • Используйте тестирование и автоматизированное тестирование (Автоматизация тестирования, Пример создания сценарного UI теста для платформы 1С)

Специальные предложения

Electronic Software Distribution

Интеграция 1С с системой Меркурий

Алкогольная декларация

Готовые переносы данных

54-ФЗ

Управление проектом на Инфостарте

Траектория обучения 1С-разработчика

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

Крутку в любом случае по коду делаешь.
Мне для того и дано колесико мышки, чтобы крутку можно было делать удобно, это не аргумент.

(1) На счет скролла кода:
1. С психологической точки зрения при постоянном переключении туда-сюда больше устаешь и соответственно теряется эффективность.
2. По некоторым рекомендациям проведения код ревью: чем меньше код и более компактный, тем проще проводить эту процедуру.
3. С точки зрения эффективности анализа кода, гораздо проще понять в чем суть:

т.е. чем компактней код тем лучше, но не всегда такого можно добиться.

"Оператор "Перейти" запрещено использовать."
Если бы все было именно так, то этого оператора не было в синтаксисе.

(4) Это правило хорошего тона. Однако, мне встречались реализации на 1С, где довольно часто использовался этот оператор. И выглядел этот кода довольно уныло.
С другой стороны, если взять Ассемблер (или машинные коды), то там как раз в большинстве своем использования операторов перехода и особенно "перейти" (jmp)

(6) при программировании конечных автоматов логичнее использовать goto,
если вы чего-то не . то это не значит что это не . .
Статья из серии "Дейкстру и Вирта не читал , но имею собственное мнение "

Пфффф, у меня по арифметике было "5"!

Выводы гениальны, конечно.. удобно использовать там, где он уместен.
Не понял, откуда у вас получился вывод, что Оператор "Перейти" использовать запрещено?

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

Читайте также: