异常:try...with 表达式 (F#)
本主题介绍 try...with 表达式,该表达式在 F# 语言中用于异常处理。
try
expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...
备注
try...with 表达式用于在 F# 中处理异常。 它与使用 C# 的 try...catch 语句类似。 在前面的语法中,expression1 中的代码可能会生成异常。 try...with 表达式将返回值。 如果未引发异常,则整个表达式将返回 expression1 的值。 如果引发了异常,则会依次将每个 pattern 与异常进行比较,并且,对于第一个匹配模式,将会执行该分支的对应 expression(称为“异常处理程序”),并且总体表达式将在该异常处理程序中返回表达式的值。 如果没有任何模式匹配,则异常将在调用堆栈中向上传播,直至找到匹配处理程序为止。 从异常处理程序中每个表达式返回的值的类型必须与从 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 as identifier。 |
identifier when condition |
如果条件为真,则与任何异常匹配。 |
示例
下面的代码示例阐释各种异常处理程序模式的用法。
// 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 表达式的自定义版本。 有关更多信息,请参见异步工作流 (F#)和计算表达式 (F#)。