异常:尝试...finally 表达式

即使代码块引发异常,表达式 try...finally 也能执行清理代码。

语法

try
    expression1
finally
    expression2

注解

表达式 try...finally 可用于在上述语法中执行 expression2 中的代码,而不考虑在执行 expression1 期间是否生成异常。

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 。 因此,如果代码需要块和块,则必须嵌套这两个withfinally构造,如下面的代码示例所示。

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

在计算表达式(包括序列表达式和异步表达式)的上下文中, 请尝试...最后 ,表达式可以具有自定义实现。 有关详细信息,请参阅 计算表达式

另请参阅