Výjimky: Výraz try...finally
Výraz try...finally
umožňuje spustit kód čištění, i když blok kódu vyvolá výjimku.
Syntaxe
try
expression1
finally
expression2
Poznámky
Výraz try...finally
lze použít ke spuštění kódu ve výrazu 2 v předchozí syntaxi bez ohledu na to, jestli se během provádění výrazu 1 vygeneruje výjimka.
Typ výrazu2 nepřispívá k hodnotě celého výrazu; typ vrácený v případě, že nedojde k výjimce, je poslední hodnotou ve výrazu1. Pokud dojde k výjimce, nevrátí se žádná hodnota a tok řízení se přenese do další odpovídající obslužné rutiny výjimky do zásobníku volání. Pokud se nenajde žádná obslužná rutina výjimky, program se ukončí. Před spuštěním kódu v odpovídající obslužné rutině nebo ukončením programu se kód ve finally
větvi spustí.
Následující kód ukazuje použití výrazu try...finally
.
let divide x y =
let stream : System.IO.FileStream = System.IO.File.Create("test.txt")
let writer : System.IO.StreamWriter = new System.IO.StreamWriter(stream)
try
writer.WriteLine("test1")
Some( x / y )
finally
writer.Flush()
printfn "Closing stream"
stream.Close()
let result =
try
divide 100 0
with
| :? System.DivideByZeroException -> printfn "Exception handled."; None
Výstup do konzoly je následující.
Closing stream
Exception handled.
Jak vidíte z výstupu, datový proud byl uzavřen před zpracování vnější výjimky a soubor test.txt
obsahuje text test1
, který označuje, že vyrovnávací paměti byly vyprázdněny a zapsány na disk, i když výjimka přenesla ovládací prvek do vnější obslužné rutiny výjimky.
Všimněte si, že try...with
konstruktor je samostatný konstruktor od konstruktoru try...finally
. Proto pokud váš kód vyžaduje with
blok i finally
blok, musíte vnořit tyto dva konstruktory, jako v následujícím příkladu kódu.
exception InnerError of string
exception OuterError of string
let function1 x y =
try
try
if x = y then raise (InnerError("inner"))
else raise (OuterError("outer"))
with
| InnerError(str) -> printfn "Error1 %s" str
finally
printfn "Always print this."
let function2 x y =
try
function1 x y
with
| OuterError(str) -> printfn "Error2 %s" str
function2 100 100
function2 100 10
V kontextu výpočetních výrazů, včetně sekvenčních výrazů a asynchronních výrazů, zkuste... výrazy finally mohou mít vlastní implementaci. Další informace naleznete v tématu Výpočetní výrazy.