📜  F#-异常处理

📅  最后修改于: 2020-11-21 06:59:35             🧑  作者: Mango


例外是在程序执行期间出现的问题。 F#异常是对程序运行时出现的异常情况的响应,例如试图除以零。

异常提供了一种将控制权从程序的一部分转移到另一部分的方法。 F#异常处理提供以下构造-

Construct Description
raise expr Raises the given exception.
failwith expr Raises the System.Exception exception.
try expr with rules Catches expressions matching the pattern rules.
try expr finally expr Execution the finally expression both when the computation is successful and when an exception is raised.
| 😕 ArgumentException A rule matching the given .NET exception type.
| 😕 ArgumentException as e A rule matching the given .NET exception type, binding the name e to the exception object value.
| Failure(msg) → expr A rule matching the given data-carrying F# exception.
| exn → expr A rule matching any exception, binding the name exn to the exception object value.
| exn when expr → expr A rule matching the exception under the given condition, binding the name exn to the exception object value.

让我们从异常处理的基本语法开始。

句法

F#异常处理块的基本语法是-

exception exception-type of argument-type

哪里,

  • exception-type是新的F#异常类型的名称。

  • arguments-type表示引发此类异常时可以提供的参数类型。

  • 可以通过使用元组类型作为参数类型来指定多个参数。

try … with表达式用于F#语言中的异常处理。

带表达式的try…的语法是-

try
   expression1
with
   | pattern1 -> expression2
   | pattern2 -> expression3
...

使用try … finally表达式,即使代码块引发异常,也可以执行清除代码。

try…finally表达式的语法是-

try
   expression1
finally
   expression2

提升函数用于指示发生了错误或异常情况。它还在异常对象中捕获有关错误的信息。

提升函数的语法是-

raise (expression)

failwith函数生成一个F#异常。

failwith函数的语法是-

failwith error-message-string

invalidArg函数生成一个参数异常。

invalidArg parameter-name error-message-string

异常处理的例子

例子1

以下程序通过一个简单的try…块展示了基本的异常处理-

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.
…

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