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 表示在引发此类型异常时可以提供的参数的类型。

  • 可以通过使用元组类型作为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# 提供了一个exception 类型用于声明异常。您可以在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.
…

根据系统,还会显示有关导致系统错误的文件和变量的其他信息。

广告

© . All rights reserved.