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