异常是在执行程序期间出现的问题. 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
其中,
例外类型是一个名称新的F#异常类型.
参数类型表示当您引发此异常时可以提供的参数类型类型.
可以使用参数类型的元组类型指定多个参数.
try ... with 表达式用于F#语言中的异常处理.
try ... with expression的语法是 :
try expression1with | pattern1 -> expression2 | pattern2 -> expression3...
try ... finally 表达式允许您执行清理代码,即使一段代码抛出一个异常.
try ... finally表达式的语法是 :
try expression1finally expression2
raise 函数用于表示发生错误或异常情况.它还捕获有关异常对象中的错误的信息.
raise函数的语法是 :
raise(expression)
failwith 函数生成F#异常.
failwith函数的语法是 :
failwith error-message-string
invalidArg 函数生成参数异常.
invalidArg parameter-name error-message-string
异常处理示例
示例1
以下程序显示使用简单的尝试进行基本的异常处理...使用块:
let divisionprog x y = try Some (x / y) with | :? System.DivideByZeroException -> printfn "Division by zero!"; Nonelet 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 * intlet 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 imyfunction 20 10myfunction 5 5
编译执行程序时,它产生以下输出 :
Error2 Error Not detected 100Error1 Equal Number Error
示例3
以下示例演示嵌套异常处理 :
exception InnerError of stringexception OuterError of stringlet 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" strfunc2 100 150func2 100 100func2 100 120
编译并执行程序时,它会产生以下输出 :
From the finally block.Error: outer errorError:inner errorFrom the finally block.From the finally block.Error: outer error
示例4
以下函数演示了 failwith function :
let divisionFunc x y = if (y = 0) then failwith "Divisor cannot be zero." else x / ylet trydivisionFunc x y = try divisionFunc x y with | Failure(msg) -> printfn "%s" msg; 0let result1 = trydivisionFunc 100 0let result2 = trydivisionFunc 100 4printfn "%A" result1printfn "%A" result2
编译并执行程序时,它会产生以下输出 :
Divisor cannot be zero.025
示例5
invalidArg function生成一个参数异常.以下程序演示了这个 :
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)
编译并执行程序时,它会产生以下输出 :
SundayThursdayUnhandled Exception:System.ArgumentException: You have entered 9.…
根据系统的不同,还将显示有关导致系统错误的文件和变量的其他信息.