本主题介绍表达式 try...with
,该表达式用于 F# 中的异常处理。
语法
try
expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...
注解
该 try...with
表达式用于处理 F# 中的异常。 它类似于 try...catch
C# 中的语句。 在前面的语法中, 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# 异常。 可以使用关键字定义 F# 异常 exception
。
可以使用各种模式来筛选异常类型和其他条件;下表汇总了这些选项。
图案 | DESCRIPTION |
---|---|
:? exception-type | 匹配指定的 .NET 异常类型。 |
:? 异常类型 作为 标识符 | 匹配指定的 .NET 异常类型,但为异常提供命名值。 |
exception-name(参数) | 匹配 F# 异常类型并绑定参数。 |
标识符 | 匹配任何异常并将名称绑定到异常对象。 等效于 :?System.Exception 作为标识符 |
条件时标识符 | 如果条件为 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
表达式。 有关详细信息,请参阅 异步表达式、 任务表达式和 计算表达式。