- F# 基礎教程
- F# - 首頁
- F# - 概述
- F# - 環境設定
- F# - 程式結構
- F# - 基本語法
- F# - 資料型別
- F# - 變數
- F# - 運算子
- F# - 決策
- F# - 迴圈
- F# - 函式
- F# - 字串
- F# - 選項
- F# - 元組
- F# - 記錄
- F# - 列表
- F# - 序列
- F# - 集合
- F# - 對映
- F# - 辨別聯合
- F# - 可變資料
- F# - 陣列
- F# - 可變列表
- F# - 可變字典
- F# - 基本輸入/輸出
- F# - 泛型
- F# - 委託
- F# - 列舉
- F# - 模式匹配
- F# - 異常處理
- F# - 類
- F# - 結構體
- F# - 運算子過載
- F# - 繼承
- F# - 介面
- F# - 事件
- F# - 模組
- F# - 名稱空間
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. …
根據系統,還會顯示有關導致系統錯誤的檔案和變數的其他資訊。
廣告