例外狀況:try...finally 運算式 (F#)
try...finally 運算式可讓您執行清除程式碼,即使有程式碼區塊擲回例外狀況也一樣。
try
expression1
finally
expression2
備註
無論 expression1 在執行期間是否產生例外狀況,try...finally 運算式都能用來執行上述語法中 expression2 的程式碼。
expression2 的型別不會做為整個運算式的值;當例外狀況未發生時傳回的型別為 expression1 中的最後一個值。 當例外狀況發生時,則不會傳回值,而且控制流程會轉移至呼叫堆疊上的下一個相符之例外處理常式。 如果找不到例外狀況處理常式,程式會終止。 在相符之處理常式中的程式碼執行前或程式終止前,finally 分支中的程式碼會執行。
下列程式碼示範 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
對主控台的輸出如下。
Closing stream
Exception handled.
從輸出中可以看見,在處理外部例外狀況前資料流已關閉,而且檔案 test.txt 包含文字 test1,這表示緩衝區已清除並寫入至磁碟,即使例外狀況將控制轉移至外部例外處理常式也一樣。
請注意,try...with 建構與 try...finally 建構是不同的建構。 因此,如果程式碼需要 with 區塊和 finally 區塊,您必須巢狀化這兩個建構,如下列程式碼範例所示。
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
在計算運算式的內容中 (包括序列運算式和非同步工作流程),try...finally 運算式可以具有自訂實作。 如需詳細資訊,請參閱計算運算式 (F#)。