Вы можете написать функцию высшего порядка, которая принимает три части как отдельную функцию. Тело try
будет функцией unit -> 'R
, где 'R
- результат. Обработчик исключений должен будет обрабатывать только некоторые исключения, поэтому вы можете вернуть option
, чтобы указать, обработали ли вы результат или хотите, чтобы исключение было переброшено. Тип обработчика будет exn -> 'R option
. Финализатор - это просто функция unit -> unit
.
Использование не так элегантно, как использование встроенной функции языка, но оно делает свое дело:
tryWithFinally
(fun () ->
1/0 ) // The nested body
(function
| :? DivideByZeroException -> Some -1 // Handle division by zero
| _ -> None ) // Rethrow any other exceptions
(fun () ->
printfn "done" )
Реализация довольно проста, если вы знаете структуру, но для полноты вот она:
let tryWithFinally f handler finalizer =
try
try f()
with e ->
match handler e with
| Some r -> r
| None -> reraise()
finally
finalizer()
В любом случае, я согласен с @pad, что в большинстве случаев у вас все будет в порядке с use
и try .. with
.