F#異常處理

2018-12-16 11:48 更新

異常是在程序執(zhí)行期間出現(xiàn)的問題。 F#異常是對程序運行時出現(xiàn)的異常情況的響應(yīng),例如嘗試除以零。
異常提供了一種將控制從程序的一個部分轉(zhuǎn)移到另一個部分的方法。 F#異常處理提供了以下結(jié)構(gòu)。

結(jié)構(gòu)描述
raise expr引發(fā)給出例外。
failwith expr引發(fā)System.Exception的異常。
try expr with rules抓住表達式匹配模式規(guī)則。
try expr finally expr當(dāng)計算成功時以及當(dāng)引發(fā)異常時,執(zhí)行finally表達式。
| :? ArgumentException規(guī)則匹配給定的.NET異常類型。
| :? ArgumentException as e規(guī)則匹配給定的.NET異常類型,綁定名稱e將異常對象值。
| Failure(msg) → expr規(guī)則匹配給定的數(shù)據(jù)承載F#異常。
| exn → expr規(guī)則匹配任何異常,結(jié)合EXN異常對象值的名稱。
| exn when expr → expr規(guī)則匹配給定條件下的例外,結(jié)合EXN異常對象值的名稱。

讓我們先從異常處理的基本語法。

語法

F#的異常處理塊基本語法 

exception exception-type of argument-type

注意,

  • exception-type是一個新的F#的異常類型的名稱。

  • argument-type代表可以當(dāng)你提出這個類型的異常提供一個參數(shù)的類型。

  • 多個參數(shù)可以通過使用自變量類型的元組類型來指定。

try ... with表達式 用于在F#語言中進行異常處理。

try ... with的語法示例

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

try ... finally表達式允許你執(zhí)行清理代碼,即使一個代碼塊拋出異常。

try ... finally的語法

try
   expression1
finally
   expression2

raise函數(shù)用于指示發(fā)生錯誤或異常情況。 它還捕獲異常對象中有關(guān)錯誤的信息。
raise函數(shù)的語法是 -

raise (expression)

failwith函數(shù)產(chǎn)生一個F#異常。

failwith函數(shù)的語法是 

failwith error-message-string

invalidArg函數(shù)生成參數(shù)異常。

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

當(dāng)你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

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

當(dāng)你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

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

當(dāng)你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

From the finally block.
Error: outer error
Error:inner error
From the finally block.
From the finally block.
Error: outer error

例4

下面的函數(shù)演示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

當(dāng)你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

Divisor cannot be zero.
0
25

例5

invalidArg函數(shù)生成參數(shù)異常。 以下程序演示了這一點 

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)

當(dāng)你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

Sunday
Thursday
Unhandled Exception:
System.ArgumentException: You have entered 9.
…

根據(jù)系統(tǒng),還將顯示有關(guān)文件和系統(tǒng)中導(dǎo)致錯誤的其他信息的其他信息。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號