F# - 异常处理
异常是程序执行过程中出现的问题。 F# 异常是对程序运行时出现的异常情况的响应,例如尝试除以零。
异常提供了一种将控制从程序的一个部分转移到另一个部分的方法。 F# 异常处理提供以下构造 −
构造 | 描述 |
---|---|
raise expr | 引发给定的异常。 |
failwith expr | 引发System.Exception异常。 |
try expr with rules | 捕获与模式规则匹配的表达式。 |
try expr finally expr | 在计算成功和引发异常时执行finally表达式。 |
| :? ArgumentException | 与给定 .NET 异常类型匹配的规则。 |
| :? ArgumentException as e | 匹配给定 .NET 异常类型的规则,将名称 e 绑定到异常对象值。 |
| Failure(msg) → expr | 与给定数据携带 F# 异常匹配的规则。 |
| exn → expr | 匹配任何异常的规则,将名称exn绑定到异常对象值。 |
| exn when expr → expr | 在给定条件下匹配异常的规则,将名称exn绑定到异常对象值。 |
让我们从异常处理的基本语法开始。
语法
F# 异常处理块的基本语法是 −
exception exception-type of argument-type
其中,
exception-type 是新的 F# 异常类型的名称。
argument-type 表示引发此类型异常时可以提供的参数类型。
可以通过使用元组类型作为参数类型来指定多个参数。
try...with 表达式用于 F# 语言中的异常处理。
try … with 表达式的语法是 −
try expression1 with | pattern1 -> expression2 | pattern2 -> expression3 ...
try...finally 表达式允许您执行清理代码,即使代码块抛出异常也是如此。
try …finally 表达式的语法是 −
try expression1 finally expression2
raise 函数用于指示发生了错误或异常情况。 它还捕获异常对象中有关错误的信息。
raise 函数的语法是 −
raise (expression)
failwith 函数生成 F# 异常。
failwith 函数的语法是 −
failwith error-message-string
invalidArg 函数生成参数异常。
invalidArg parameter-name error-message-string
异常处理示例
示例 1
下面的程序通过一个简单的 try…with 块展示了基本的异常处理 −
let divisionprog x y = try Some (x / y) with | :? System.DivideByZeroException -> printfn "Division by zero!"; None let result1 = divisionprog 100 0
当您编译并执行该程序时,它会产生以下输出 −
Division by zero!
示例 2
F# 提供了用于声明异常的异常类型。 您可以直接在 try...with 表达式的过滤器中使用异常类型。
以下示例演示了这一点 −
exception Error1 of string // Using a tuple type as the argument type. exception Error2 of string * int let myfunction x y = try if x = y then raise (Error1("Equal Number Error")) else raise (Error2("Error Not detected", 100)) with | Error1(str) -> printfn "Error1 %s" str | Error2(str, i) -> printfn "Error2 %s %d" str i myfunction 20 10 myfunction 5 5
当您编译并执行该程序时,它会产生以下输出 −
Error2 Error Not detected 100 Error1 Equal Number Error
示例 3
以下示例演示了嵌套异常处理 −
exception InnerError of string exception OuterError of string let func1 x y = try try if x = y then raise (InnerError("inner error")) else raise (OuterError("outer error")) with | InnerError(str) -> printfn "Error:%s" str finally printfn "From the finally block." let func2 x y = try func1 x y with | OuterError(str) -> printfn "Error: %s" str func2 100 150 func2 100 100 func2 100 120
当您编译并执行该程序时,它会产生以下输出 −
From the finally block. Error: outer error Error:inner error From the finally block. From the finally block. Error: outer error
示例 4
以下函数演示了failwith函数 −
let divisionFunc x y = if (y = 0) then failwith "Divisor cannot be zero." else x / y let trydivisionFunc x y = try divisionFunc x y with | Failure(msg) -> printfn "%s" msg; 0 let result1 = trydivisionFunc 100 0 let result2 = trydivisionFunc 100 4 printfn "%A" result1 printfn "%A" result2
当您编译并执行该程序时,它会产生以下输出 −
Divisor cannot be zero. 0 25
示例 5
invalidArg 函数生成参数异常。 下面的程序演示了这一点 −
let days = [| "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday" |] let findDay day = if (day > 7 || day < 1) then invalidArg "day" (sprintf "You have entered %d." day) days.[day - 1] printfn "%s" (findDay 1) printfn "%s" (findDay 5) printfn "%s" (findDay 9)
当您编译并执行该程序时,它会产生以下输出 −
Sunday Thursday Unhandled Exception: System.ArgumentException: You have entered 9. …
有关导致系统错误的文件和变量的一些其他信息也会显示,具体取决于系统。