Вариант против исключения в обработке исключений
После использования F# option
на некоторое время, я понимаю, что это может быть использовано для обработки исключительных случаев. Я могу использовать либо option
или же Exception
в следующих примерах:
-
find
функции из модулей List/Array/SeqKeyNotFoundException
в редких случаях при соответствующемtryFind
возврат партнеровNone
в этих ситуациях. - Когда я выполняю возврат (при решении N-ферзей, Судоку и т. Д.), Когда у ветви нет решения, я могу либо вызвать исключение и перехватить его позже, либо вернуть None, чтобы сопоставить это значение с возвратом. Эти случаи происходят довольно часто, пока мы не найдем решение.
У меня сложилось впечатление option
это более функциональный подход, в то время как Exception
чаще используется в платформе.NET.
Каковы различия между option
а также Exception
в обработке исключений с точки зрения удобства использования, производительности и т. д.? В каких случаях лучше использовать технику, чем другую?
4 ответа
CLR делает операцию метания и ловли исключительной ситуации чрезвычайно дорогой. Только по этой причине вы должны предпочесть такие конструкции, как Option, для сообщения об ожидаемых сбоях. Если сбой действительно исключительный и почти неустранимый, продолжайте и выбросьте исключение. Но, как вы заметили, такие вещи, как возврат в процессе поиска, не являются исключительными, и вы обнаружите, что ваша производительность сильно пострадает, если вы реализуете их с исключениями.
Поскольку это свойство CLR, на самом деле не имеет значения, находитесь ли вы в F# или нет. Насколько я понимаю, другие среды выполнения для ML-подобных языков, например ocaml, не имеют этой характеристики и поэтому могут чаще использовать исключения для потока управления.
Мой вопрос: в чем различия между Option и Exception при обработке исключений с точки зрения удобства использования, производительности...?
option
Тип предлагает более строгую статическую проверку, чем исключения, увеличивая вероятность того, что ошибка программиста будет обнаружена компилятором. Возвращение в порядке исключения скорее всего будет быстрее, чем возвращение Some
результат, но возвращение исключительно в сотни раз медленнее, чем возвращение None
,
В каких случаях использование техники лучше, чем другой?
Всякий раз, когда я пишу код, такой как серверы и демоны, которые должны работать, я ловлю как можно больше исключений и заменяю их значениями типов объединения, таких как option
, Затем система статических типов вынуждает меня обрабатывать как исключительные, так и неисключительные возвраты почти во всех случаях, что значительно упрощает написание кода, который не погибнет от неожиданного распространения исключения.
С теоретической точки зрения. option
это то, что вы должны использовать в тех функциях, которые являются чисто с точки зрения FP (вы можете гуглить о том, что такое чистые функции). Исключения больше относятся к нечистому миру (как мир ввода-вывода в Хаскеле).
Теперь с практической точки зрения я бы предложил использовать option
в качестве типа возврата, когда логика вашего приложения говорит, что значение может быть там или не может быть, то есть значение, которое не присутствует, является допустимым правилом приложения. Исключения - это то, что должно возникать, когда что-то происходит в логике приложения, что указывает на неправильное выполнение логики или некоторое неправильное состояние приложения, которое не ожидалось в соответствии с правилами приложения.
Из производительности POV генерирование исключения является более дорогостоящим (из-за разматывания стека - поиск соответствующего обработчика исключения и т. Д.) По сравнению с возвращаемыми типами опций.
С точки зрения удобства использования я предпочитаю варианты в F#.
- Опции инкапсулируют исключительное состояние, а также ожидаемое состояние. Это позволяет отложить обработку исключительного состояния до тех пор, пока вам не понадобится ожидаемое состояние.
- В Option также есть несколько вспомогательных функций, которые вы должны написать сами, за исключением.
- Частичные активные шаблоны позволяют очень аккуратно обрабатывать несколько исключительных случаев с помощью опций.
- Необязательные параметры в F# реализованы с помощью параметров. Эта отложенная природа, о которой я упоминал выше, позволяет вам не заботиться о том, что послужило причиной исключительного случая, при условии, что потребитель имеет для него значение по умолчанию.
Опции - это принципиально иное представление об исключительных случаях, и я считаю, что они помогают сделать F# особенным.