F # - Xử lý Ngoại lệ

Một ngoại lệ là một vấn đề phát sinh trong quá trình thực hiện một chương trình. Một ngoại lệ F # là một phản ứng đối với một trường hợp đặc biệt phát sinh trong khi chương trình đang chạy, chẳng hạn như một nỗ lực chia cho số không.

Ngoại lệ cung cấp một cách để chuyển quyền kiểm soát từ một phần của chương trình sang phần khác. Xử lý ngoại lệ F # cung cấp các cấu trúc sau:

Xây dựng Sự miêu tả
nâng cao expr Tăng ngoại lệ đã cho.
failwith expr Nâng cao System.Exception ngoại lệ.
thử expr với các quy tắc Bắt các biểu thức phù hợp với các quy tắc mẫu.
thử expr cuối cùng expr Thực hiện finally biểu thức cả khi tính toán thành công và khi một ngoại lệ được đưa ra.
| :? ArgumentException Quy tắc phù hợp với loại ngoại lệ .NET đã cho.
| :? ArgumentException as e Quy tắc khớp với loại ngoại lệ .NET đã cho, ràng buộc tên e thành giá trị đối tượng ngoại lệ.
| Thất bại (msg) → expr Quy tắc phù hợp với ngoại lệ F # mang dữ liệu đã cho.
| exn → expr Quy tắc phù hợp với bất kỳ ngoại lệ nào, ràng buộc tên exn thành giá trị đối tượng ngoại lệ.
| exn khi expr → expr Quy tắc phù hợp với ngoại lệ trong điều kiện đã cho, ràng buộc tên exn thành giá trị đối tượng ngoại lệ.

Chúng ta hãy bắt đầu với cú pháp cơ bản của Xử lý ngoại lệ.

Cú pháp

Cú pháp cơ bản cho khối xử lý ngoại lệ F # là:

exception exception-type of argument-type

Ở đâu,

  • exception-type là tên của kiểu ngoại lệ F # mới.

  • argument-type đại diện cho loại đối số có thể được cung cấp khi bạn nêu ra một ngoại lệ của loại này.

  • Nhiều đối số có thể được chỉ định bằng cách sử dụng một kiểu tuple cho kiểu đối số.

Các try...with biểu thức được sử dụng để xử lý ngoại lệ trong ngôn ngữ F #.

Cú pháp của try… với biểu thức là -

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

Các try...finally biểu thức cho phép bạn thực thi mã xóa ngay cả khi một khối mã ném một ngoại lệ.

Cú pháp cho biểu thức try ... cuối cùng là -

try
   expression1
finally
   expression2

Các raisehàm được sử dụng để chỉ ra rằng một lỗi hoặc điều kiện ngoại lệ đã xảy ra. Nó cũng nắm bắt thông tin về lỗi trong một đối tượng ngoại lệ.

Cú pháp cho hàm raise là -

raise (expression)

Các failwith hàm tạo ra một ngoại lệ F #.

Cú pháp cho hàm failwith là:

failwith error-message-string

Các invalidArg hàm tạo ra một ngoại lệ đối số.

invalidArg parameter-name error-message-string

Ví dụ về Xử lý Ngoại lệ

ví dụ 1

Chương trình sau đây cho thấy cách xử lý ngoại lệ cơ bản với một thử đơn giản… với khối -

let divisionprog x y =
   try
      Some (x / y)
   with
      | :? System.DivideByZeroException -> printfn "Division by zero!"; None

let result1 = divisionprog 100 0

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Division by zero!

Ví dụ 2

F # cung cấp một exceptionloại để khai báo ngoại lệ. Bạn có thể sử dụng một loại ngoại lệ trực tiếp trong các bộ lọc trongtry...with biểu hiện.

Ví dụ sau đây chứng minh điều này -

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

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Error2 Error Not detected 100
Error1 Equal Number Error

Ví dụ 3

Ví dụ sau minh họa việc xử lý ngoại lệ lồng nhau:

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

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

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

Ví dụ 4

Hàm sau thể hiện failwith chức năng -

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

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Divisor cannot be zero.
0
25

Ví dụ 5

Các invalidArghàm tạo ra một ngoại lệ đối số. Chương trình sau đây chứng minh điều này -

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)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

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

Một số thông tin khác về tệp và biến gây ra lỗi trong hệ thống cũng sẽ được hiển thị, tùy thuộc vào hệ thống.