Я только что обнаружил прекрасный код в приложении нашей компании, в котором в качестве логических операторов используются блоки Try-Catch.
Это означает: «создайте некоторый код, если при этом выдается эта ошибка, сделайте этот код, но если при этом выдается эта ошибка, сделайте вместо этого эту третью вещь».
Он использует «И наконец» в качестве «другого» выражения, которое появляется.
Я знаю, что это неправильно по своей сути, но прежде чем начать драку, я надеялся на некоторые хорошо продуманные аргументы.
И, эй, если у вас есть аргументы ЗА использование Try-Catch таким образом, пожалуйста, сообщите.
Для тех, кто интересуется, язык C #, а рассматриваемый код содержит более 30 строк и ищет конкретные исключения, он не обрабатывает ВСЕ исключения.
источник
try
'd. Не каждый исключительный случай, который требует исключения вообще, должен быть фатальным в этом конкретном случае. Итак, не могли бы вы сделать это более простым, одинаково или более надежным способом без использования исключений?Ответы:
Обработка исключений, как правило, является дорогостоящим способом управления потоком (конечно, для C # и Java).
Среда выполнения выполняет довольно много работы, когда создается объект исключения - сборка трассировки стека, выяснение, где обрабатывается исключение и многое другое.
Все это стоит в памяти и процессорных ресурсах, которые не нужно расширять, если для управления потоком используются операторы управления потоком.
Кроме того, существует семантическая проблема. Исключения - для исключительных ситуаций, а не для нормального управления потоком. Нужно использовать обработку исключений для обработки непредвиденных / исключительных ситуаций, а не как обычный поток программ, потому что в противном случае необработанное исключение скажет вам гораздо меньше.
Помимо этих двух, есть дело, что другие читают код. Использование исключений таким образом - это не то, чего ожидают большинство программистов, так что читаемость и насколько понятен ваш код. Когда кто-то видит «Исключение», он думает - что-то плохое случилось, что-то, что не должно происходить нормально. Таким образом, использование исключений таким способом просто сбивает с толку.
источник
Откуда ты это знаешь? Я отказался от всех этих «знаний» и теперь просто считаю, что самый простой код - лучший. Предположим, вы хотите преобразовать строку в необязательный, который будет пустым, если анализ не удастся. В этом нет ничего плохого:
Я полностью не согласен с обычной интерпретацией «Исключения для исключительных условий». Если функция не может вернуть пригодное для использования значение или метод не может выполнить свои постусловия, выдается исключение. Неважно, как часто эти исключения генерируются, пока не будет продемонстрирована проблема с производительностью.
Исключения упрощают код, позволяя отделить обработку ошибок от обычного потока. Просто напишите самый простой из возможных кодов, и, если проще использовать try-catch или вызвать исключение, сделайте это.
Исключения упрощают тестирование, уменьшая количество путей в коде. Функция без ветвей завершит или сгенерирует исключение. Функция с несколькими
if
операторами для проверки кодов ошибок имеет много возможных путей. Очень легко ошибиться в одном из условий или полностью его забыть, так что некоторые условия ошибки игнорируются.источник
int i; if(long.TryParse(s, out i)) return i; else return null;
. TryParse возвращает false, если строка не может быть проанализирована. Если он может быть проанализирован, он устанавливает выходной аргумент в результаты анализа и возвращает true. Никаких исключений не возникает (даже внутренне в TryParse), и особенно нет исключений, которые относятся к типу, который означает ошибку программиста, какFormatException
всегда указывает .NET .Отладка и обслуживание очень трудны, когда поток управления выполняется с использованием исключений.
По сути, исключения предназначены для того, чтобы стать механизмом для изменения нормального потока управления вашей программы - выполнения необычных действий, вызывающих необычные побочные эффекты, как способа выйти из особенно тесного связывания, которое не может быть обработано с помощью менее сложных средства. Исключения являются исключительными. Это означает, что в зависимости от того, в какой конкретной среде вы работаете, использование исключения для регулярного потока управления может вызвать:
Неэффективность Дополнительные обходы, через которые должна пройти среда, чтобы безопасно выполнить относительно сложные изменения контекста, необходимые для исключений, требуют инструментария и ресурсов.
Трудности отладки Иногда полезная (при попытке отладки программы) информация выбрасывается в окно при возникновении исключений. Вы можете потерять отслеживание состояния программы или истории, которая важна для понимания поведения во время выполнения
Проблемы с обслуживанием Порядок выполнения трудно проследить через скачки исключений. Кроме того, исключение может вызываться изнутри кода типа черного ящика, который может вести себя непонятным образом при создании исключения.
Плохие дизайнерские решения Программы, созданные таким образом, способствуют формированию умонастроения, которое в большинстве случаев нелегко сочетается с элегантным решением проблем. Сложность окончательной программы не позволяет программисту полностью понять ее исполнение и поощряет принятие решений, которые приводят к краткосрочным улучшениям с высокими долгосрочными затратами.
источник
Я видел, как эта модель использовалась несколько раз.
Есть 2 основные проблемы:
goto
. Прыжки считаются вредными по ряду причин. Их следует использовать, если все альтернативы имеют значительные недостатки. На самом деле, во всем моем коде я помню только 2 случая, когда переходы были явно лучшим решением.источник
Иногда исключения самые быстрые. Я видел случаи, когда исключения нулевых объектов были быстрее даже в Java, чем при использовании управляющих структур (в данный момент я не могу процитировать исследование, поэтому вам придется мне доверять). Проблема возникает, когда Java фактически требует времени и заполняет трассировку стека пользовательского класса исключений вместо использования собственных (которые, по-видимому, по крайней мере частично кэшированы). Прежде чем сказать, что что-то происходит в одностороннем порядке быстрее или медленнее, было бы хорошо для сравнения.
В Python это не только быстрее, но и гораздо правильнее сделать что-то, что может вызвать исключение, а затем обработать ошибку. Да, вы можете применять систему типов, но это противоречит философии языка - вместо этого вы должны просто попытаться вызвать метод и поймать результат! (Проверка, является ли файл доступным для записи, похожа - просто попробуйте записать в него и поймать ошибку).
Я видел случаи, когда быстрее было бы сделать что-то глупое, например таблицы запросов, которых там не было, чем выяснить, существует ли таблица в PHP + MySQL ( вопрос, где я проверяю это, на самом деле мой единственный принятый ответ с отрицательным голосом) ,
Все это говорит о том, что использование исключений должно быть ограничено по нескольким причинам:
try...catch
сторонники потока управления обычно (по моему опыту) не следуют философии «минимизировать код в блоке попытки».else if
блока. Достаточно сказано (и если кто-то возражает с «Но они могут использовать разные классы исключений», мой ответ: «Иди в свою комнату и не выходи, пока не подумаешь о том, что сказал»).Exception
для остального мира (как не для приверженцевtry...catch
философии потока управления) означает, что что-то вошло в нестабильное (хотя, возможно, восстанавливаемое) состояние. Нестабильные состояния - ПЛОХО, и это должно держать нас всех ночью, если у нас действительно есть исключения, которых можно избежать (это на самом деле меня пугает, нет лжи).try...catch
поток управления идет вразрез с тем, что обычно считается наилучшей практикой. Это означает, что новичку в проекте потребуется больше времени, чтобы изучить проект, что означает увеличение количества человеко-часов без какой-либо выгоды.try{ obj.openSomething(); /*something which causes exception*/ obj.doStuff(); obj.closeSomething();}catch(Exception e){obj.closeSomething();}
. В более традиционномif...else
сценарииcloseSomething()
копирование и вставка менее вероятно (опять же, из личного опыта). (Следует признать, что этот конкретный аргумент больше связан с людьми, с которыми я встречался, чем с реальной философией).источник
Мой главный аргумент в том, что использование try / catch для логики прерывает логический поток. Следование «логике» через нелогические конструкции является (для меня) нелогичным и запутанным. Я привык читать свою логику как «если условие, то A еще B». Чтение того же утверждения, что и «Попробуйте A catch, затем выполните B», кажется странным. Было бы еще более странно, если оператор
A
- это простое присваивание, требующее дополнительного кода для принудительного исключения, еслиcondition
оно ложно (и выполнение этого, вероятно, вif
любом случае потребует -соглашения).источник
Ну, просто вопрос этикета, прежде чем «начинать с ними спор», как вы говорите, я бы любезно спросил: «Почему они используют обработку исключений во всех этих разных местах?»
Я имею в виду, есть несколько возможностей:
... Я думаю, что все это одинаково вероятно. Так что просто спросите их приятно.
источник
Try Catch следует использовать только для обработки исключений. Более того, специфическая обработка исключений. Ваш пробный улов должен отлавливать только ожидаемые исключения, в противном случае он сформирован неправильно. Если вам нужно использовать catch all try catch, то вы, вероятно, делаете что-то не так.
РЕДАКТИРОВАТЬ:
Причина: Вы можете утверждать, что если вы используете try catch в качестве условного оператора, как вы собираетесь учитывать РЕАЛЬНЫЕ исключения?
источник
catch
предложении, отличном от того, которое ловит «нереальные» исключения?Исключением являются случаи, когда происходят исключительные вещи. Исключительно ли функционирует программа в соответствии с обычным рабочим процессом?
источник
Причина использования исключений:
Причины не использовать исключения:
В конце:
Цель состоит в том, чтобы написать код, который сообщает, что происходит. Исключения могут помочь / помешать этому в зависимости от того, что делает код. Попробовать / поймать в Python для KeyError в справочнике словаря (если вы знаете язык) идеально.
источник
Я использую try-> catch в качестве управления потоком в определенных ситуациях. Если ваша основная логика зависит от чего-то, что терпит неудачу, но вы не хотите просто генерировать исключение и выходить ... Вот для чего предназначен блок try-> catch. Я пишу много неконтролируемых серверных сценариев Unix, и для них гораздо важнее не потерпеть неудачу, чем сделать так, чтобы они потерпели неудачу красиво.
Так что попробуйте План A, и если План A умирает, поймайте и запустите с Планом B ... А если план B потерпит неудачу, используйте, наконец, план Plan C, который либо исправит одну из неисправных служб в A или B, либо страницу меня.
источник
Это зависит от языка и, возможно, от используемой реализации. Стандарт C ++ состоит в том, что исключения должны быть сохранены для действительно исключительных событий. С другой стороны, в Python одно из указаний гласит: « Проще просить прощения, чем разрешения », поэтому поощряется интеграция блоков try / исключением в логику программы.
источник
Это плохая привычка, но я делаю это время от времени на питоне. Например, вместо того, чтобы проверить, существует ли файл, я просто пытаюсь удалить его. Если это вызывает исключение, я ловлю и просто продолжаю, зная, что его там нет. <== (не обязательно верно, если файл принадлежит другому пользователю, но я делаю это в домашнем каталоге пользователя, поэтому это НЕ ДОЛЖНО происходить).
Тем не менее, чрезмерное использование это плохая практика.
источник
Мне нравится, как Apple это определяет : исключения только для ошибок программистов и фатальных ошибок времени выполнения. Остальное используйте коды ошибок. Это помогает мне решить, когда его использовать, подумав про себя: «Это ошибка программиста?»
источник
Это похоже на использование обработки исключений для построения логики goto поверх языка, в котором нет команды goto.
По многим причинам, по которым логика goto плоха, вы можете обратиться к этому вопросу: https://stackoverflow.com/questions/46586/goto-still-considered-harmful
источник