F # - Gestione delle eccezioni

Un'eccezione è un problema che sorge durante l'esecuzione di un programma. Un'eccezione F # è una risposta a una circostanza eccezionale che si verifica durante l'esecuzione di un programma, ad esempio un tentativo di divisione per zero.

Le eccezioni forniscono un modo per trasferire il controllo da una parte all'altra di un programma. La gestione delle eccezioni F # fornisce i seguenti costrutti:

Costruire Descrizione
aumentare expr Genera l'eccezione data.
failwith expr Alza il System.Exception eccezione.
prova expr con le regole Cattura le espressioni che corrispondono alle regole del modello.
prova infine expr expr Esecuzione del finally espressione sia quando il calcolo ha esito positivo sia quando viene sollevata un'eccezione.
| :? ArgumentException Una regola che corrisponde al tipo di eccezione .NET specificato.
| :? ArgumentException come e Una regola che corrisponde al tipo di eccezione .NET specificato, che lega il nome e al valore dell'oggetto eccezione.
| Errore (msg) → expr Una regola che corrisponde all'eccezione F # di trasporto dati specificata.
| exn → expr Una regola che corrisponde a qualsiasi eccezione, vincolando il nome exn al valore dell'oggetto eccezione.
| exn quando expr → expr Una regola che corrisponde all'eccezione in una determinata condizione, vincolando il nome exn al valore dell'oggetto eccezione.

Cominciamo con la sintassi di base della gestione delle eccezioni.

Sintassi

La sintassi di base per il blocco di gestione delle eccezioni F # è:

exception exception-type of argument-type

Dove,

  • exception-type è il nome di un nuovo tipo di eccezione F #.

  • argument-type rappresenta il tipo di un argomento che può essere fornito quando si solleva un'eccezione di questo tipo.

  • È possibile specificare più argomenti utilizzando un tipo di tupla per il tipo di argomento.

Il try...with espressione viene utilizzata per la gestione delle eccezioni nel linguaggio F #.

La sintassi per il tentativo ... con l'espressione è -

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

Il try...finally espressione consente di eseguire il codice di ripulitura anche se un blocco di codice genera un'eccezione.

Sintassi per il tentativo ... finalmente l'espressione è -

try
   expression1
finally
   expression2

Il raiseviene utilizzata per indicare che si è verificato un errore o una condizione eccezionale. Cattura anche le informazioni sull'errore in un oggetto eccezione.

La sintassi per la funzione raise è -

raise (expression)

Il failwith la funzione genera un'eccezione F #.

La sintassi per la funzione failwith è:

failwith error-message-string

Il invalidArg la funzione genera un'eccezione di argomento.

invalidArg parameter-name error-message-string

Esempio di gestione delle eccezioni

Esempio 1

Il seguente programma mostra la gestione delle eccezioni di base con un semplice tentativo ... con blocco -

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

let result1 = divisionprog 100 0

Quando compili ed esegui il programma, restituisce il seguente output:

Division by zero!

Esempio 2

F # fornisce un file exceptiontipo per la dichiarazione delle eccezioni. È possibile utilizzare un tipo di eccezione direttamente nei filtri in un filetry...with espressione.

Il seguente esempio lo dimostra:

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

Quando compili ed esegui il programma, restituisce il seguente output:

Error2 Error Not detected 100
Error1 Equal Number Error

Esempio 3

L'esempio seguente mostra la gestione delle eccezioni annidate:

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

Quando compili ed esegui il programma, restituisce il seguente output:

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

Esempio 4

La seguente funzione mostra il failwith funzione -

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

Quando compili ed esegui il programma, restituisce il seguente output:

Divisor cannot be zero.
0
25

Esempio 5

Il invalidArgla funzione genera un'eccezione di argomento. Il seguente programma lo dimostra:

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)

Quando compili ed esegui il programma, restituisce il seguente output:

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

Verranno visualizzate anche alcune altre informazioni sul file e sulla variabile che causano l'errore nel sistema, a seconda del sistema.