异常:try...with 表达式

本主题介绍 try...with 表达式,该表达式用于处理 F# 中的异常。

语法

try
    expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...

备注

try...with 表达式用于处理 F# 中的异常。 它类似于 C# 中的 try...catch 语句。 在以上语法中,expression1 中的代码可能会生成异常。 try...with 表达式返回一个值。 如果未引发异常,则整个表达式将返回 expression1 值。 如果引发异常,则分别将每种模式与异常进行比较,对于第一种匹配模式,将执行该分支的相应表达式(称为异常处理程序)并且整个表达式返回该异常处理程序中表达式的值。 如果没有模式匹配,异常会向上传播调用堆栈,直到找到匹配的处理程序。 从异常处理程序中的每个表达式返回的值的类型必须与 try 块中表达式返回的类型匹配。

通常,发生错误也意味着没有可从每个异常处理程序中的表达式返回的有效值。 常见的模式是使表达式的类型成为选项类型。 下面的代码示例阐释了这一模式。

let divide1 x y =
   try
      Some (x / y)
   with
      | :? System.DivideByZeroException -> printfn "Division by zero!"; None

let result1 = divide1 100 0

异常可以是 .NET 异常,也可以是 F# 异常。 可使用 exception 关键字定义 F# 异常。

可使用各种模式来筛选异常类型和其他条件;下表汇总了这些选项。

模式 说明
:? exception-type 匹配指定的 .NET 异常类型。
:? exception-type as identifier 匹配指定的 .NET 异常类型,但为异常提供命名值。
exception-name(arguments) 匹配 F# 异常类型并绑定参数。
identifier 匹配任何异常,将名称绑定到异常对象。 等效于 :? System.Exception asidentifier
identifier when condition 如果条件为 true,则匹配任何异常。

示例

下面的代码示例演示了各种异常处理程序模式的使用。

// This example shows the use of the as keyword to assign a name to a
// .NET exception.
let divide2 x y =
  try
    Some( x / y )
  with
    | :? System.DivideByZeroException as ex -> printfn "Exception! %s " (ex.Message); None

// This version shows the use of a condition to branch to multiple paths
// with the same exception.
let divide3 x y flag =
  try
     x / y
  with
     | ex when flag -> printfn "TRUE: %s" (ex.ToString()); 0
     | ex when not flag -> printfn "FALSE: %s" (ex.ToString()); 1

let result2 = divide3 100 0 true

// This version shows the use of F# exceptions.
exception Error1 of string
exception Error2 of string * int

let function1 x y =
   try
      if x = y then raise (Error1("x"))
      else raise (Error2("x", 10))
   with
      | Error1(str) -> printfn "Error1 %s" str
      | Error2(str, i) -> printfn "Error2 %s %d" str i

function1 10 10
function1 9 2

注意

try...with 构造是独立于 try...finally 表达式的表达式。 因此,如果代码同时需要 with 块和 finally 块,则需要嵌套这两个表达式。

注意

可在异步表达式、任务表达式和其他计算表达式中使用 try...with,在这种情况下,需要使用自定义版本的 try...with 表达式。 有关详细信息,请参阅异步表达式任务表达式计算表达式

另请参阅