Опция против исключения при обработке исключений

#.net #exception-handling #f# #option

#.net #исключение #f# #тип параметра

Вопрос:

После использования F # option type некоторое время я понимаю, что его можно использовать для обработки исключительных случаев. Я могу использовать либо option или Exception в следующих примерах:

  1. find Функции из модулей List / Array / Seq вызываются KeyNotFoundException в редких случаях, в то время как соответствующие tryFind аналоги возвращаются None в этих ситуациях.
  2. Когда я выполняю отслеживание (при решении N-queens, судоку и т. Д.), Всякий раз, Когда в ветке нет решения, я могу либо вызвать исключение и перехватить его позже, либо вернуть None, чтобы соответствовать этому значению для возврата. Такие случаи происходят довольно часто, пока мы не найдем решение.

У меня сложилось впечатление option , что это более функциональный подход, хотя Exception он чаще используется на платформе .NET.

В чем различия между option Exception обработкой исключений и обработкой исключений с точки зрения удобства использования, производительности и т. Д.? В каких случаях использование одного метода лучше, чем использование другого?

Ответ №1:

Среда CLR делает операцию создания и перехвата исключения чрезвычайно дорогостоящей. Только по этой причине вы должны предпочесть конструкции, подобные Option, для сообщения об ожидаемых сбоях. Если сбой действительно исключительный и почти неустранимый, продолжайте и создайте исключение. Но, как вы заметили, такие вещи, как возврат во время поиска, являются обычными, и вы обнаружите, что ваша производительность сильно страдает, если вы реализуете их с исключениями.

Поскольку это свойство среды CLR, на самом деле не имеет значения, находитесь ли вы в F # или нет. Насколько я понимаю, другие среды выполнения для ML-подобных языков, например ocaml, не имеют этой характеристики и поэтому могут чаще использовать исключения для потока управления.

Комментарии:

1. Действительно, я однажды измерил это и обнаружил, что исключения C в 6 раз медленнее, чем OCaml, а .NET — в 600 раз медленнее, чем OCaml!

Ответ №2:

Мой вопрос в том, в чем различия между опцией и исключением при обработке исключений с точки зрения удобства использования, производительности …?

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

В каких случаях использование одного метода лучше, чем другого?

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

Ответ №3:

С теоретической точки зрения. option это то, что вы должны использовать в тех функциях, которые являются чистыми с точки зрения FP (вы можете узнать в Google, что такое чистые функции). Исключения больше относятся к нечистому миру (например, к миру ввода-вывода в Haskell).

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

С точки зрения производительности выбрасывание исключения обходится дороже (из-за разматывания стека — поиска соответствующего обработчика исключений — и т. Д.) По сравнению с возвращением типов опций.

Комментарии:

1. Я не согласен с комментарием о производительности. Типы опций более легкие, чем типы исключений (см. Ответ @Sebastian Good).

2. В моем тексте говорится exception which will bad .. это означает, что исключения не очень хороши в производительности

3. 1; Тем не менее, вы можете перефразировать свое последнее предложение, поскольку у меня тоже возникли проблемы с его правильной интерпретацией.

4. Обновлено последнее предложение о производительности, я надеюсь, что теперь оно намного понятнее, чем предыдущее, со странным рекурсивным видом 🙂

Ответ №4:

С точки зрения удобства использования я предпочитаю опции в F #.

  • Параметры инкапсулируют исключительное состояние, а также ожидаемое состояние. Это позволяет вам отклонять обработку исключительного состояния до тех пор, пока вам не понадобится ожидаемое состояние.
  • Опция также имеет ряд вспомогательных функций, которые вам придется писать самостоятельно с исключениями.
  • Частичные активные шаблоны позволяют очень аккуратно обрабатывать несколько исключительных случаев с помощью опций.
  • Необязательные параметры в F # реализованы с помощью опций. Этот отложенный характер, о котором я упоминал выше, позволяет вам не заботиться о том, что породило исключительный случай, если у потребителя есть значение по умолчанию для него.

Опции — это принципиально иной способ мышления об исключительных случаях, и я считаю, что это помогает сделать F # особенным.

Комментарии:

1. 1 за очень вдумчивый ответ. Это то, что я хочу знать об использовании опции при обработке исключений.