Ruggine - Gestione degli errori
In Rust, gli errori possono essere classificati in due categorie principali come mostrato nella tabella seguente.
Suor n | Nome e descrizione | Utilizzo |
---|---|---|
1 | Recoverable Errori che possono essere gestiti |
Enumerazione dei risultati |
2 | UnRecoverable Errori che non possono essere gestiti |
macro di panico |
Un errore recuperabile è un errore che può essere corretto. Un programma può ritentare l'operazione non riuscita o specificare un'azione alternativa quando rileva un errore recuperabile. Gli errori ripristinabili non provocano il malfunzionamento improvviso di un programma. Un esempio di errore recuperabile è l'errore File non trovato .
Errori irreversibili causano il malfunzionamento di un programma. Un programma non può tornare al suo stato normale se si verifica un errore irreversibile. Non può ritentare l'operazione non riuscita o annullare l'errore. Un esempio di errore irreversibile è il tentativo di accedere a una posizione oltre la fine di un array.
A differenza di altri linguaggi di programmazione, Rust non ha eccezioni. Restituisce un'enumerazione Risultato <T, E> per gli errori recuperabili, mentre chiama il filepanicmacro se il programma rileva un errore irreversibile. La macro panico provoca la chiusura improvvisa del programma.
Macro di panico ed errori irreversibili
panico! consente a un programma di terminare immediatamente e fornire un feedback al chiamante del programma. Dovrebbe essere usato quando un programma raggiunge uno stato irrecuperabile.
fn main() {
panic!("Hello");
println!("End of main"); //unreachable statement
}
Nell'esempio sopra, il programma terminerà immediatamente quando incontra il panico! macro.
Produzione
thread 'main' panicked at 'Hello', main.rs:3
Illustrazione: panico! macro
fn main() {
let a = [10,20,30];
a[10]; //invokes a panic since index 10 cannot be reached
}
L'output è come mostrato di seguito:
warning: this expression will panic at run-time
--> main.rs:4:4
|
4 | a[10];
| ^^^^^ index out of bounds: the len is 3 but the index is 10
$main
thread 'main' panicked at 'index out of bounds: the len
is 3 but the index is 10', main.rs:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Un programma può invocare il panico! macro se le regole aziendali vengono violate come mostrato nell'esempio seguente:
fn main() {
let no = 13;
//try with odd and even
if no%2 == 0 {
println!("Thank you , number is even");
} else {
panic!("NOT_AN_EVEN");
}
println!("End of main");
}
L'esempio precedente restituisce un errore se il valore assegnato alla variabile è dispari.
Produzione
thread 'main' panicked at 'NOT_AN_EVEN', main.rs:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Enumerazione dei risultati ed errori ripristinabili
Enum Result - <T, E> può essere utilizzato per gestire gli errori recuperabili. Ha due varianti:OK e Err. T e E sono parametri di tipo generico. T rappresenta il tipo di valore che verrà restituito in un caso di successo nella variante OK e E rappresenta il tipo di errore che verrà restituito in un caso di errore all'interno della variante Err.
enum Result<T,E> {
OK(T),
Err(E)
}
Facci capire questo con l'aiuto di un esempio:
use std::fs::File;
fn main() {
let f = File::open("main.jpg");
//this file does not exist
println!("{:?}",f);
}
Il programma restituisce OK (File) se il file esiste già e Err (Errore) se il file non viene trovato.
Err(Error { repr: Os { code: 2, message: "No such file or directory" } })
Vediamo ora come gestire la variante Err.
L'esempio seguente gestisce un errore restituito durante l'apertura del file utilizzando l'estensione match dichiarazione
use std::fs::File;
fn main() {
let f = File::open("main.jpg"); // main.jpg doesn't exist
match f {
Ok(f)=> {
println!("file found {:?}",f);
},
Err(e)=> {
println!("file not found \n{:?}",e); //handled error
}
}
println!("end of main");
}
NOTE- Il programma stampa fine della principale manifestazione anche se il file non è stato trovato. Ciò significa che il programma ha gestito correttamente l'errore.
Produzione
file not found
Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
end of main
Illustrazione
La funzione is_even restituisce un errore se il numero non è un numero pari. La funzione main () gestisce questo errore.
fn main(){
let result = is_even(13);
match result {
Ok(d)=>{
println!("no is even {}",d);
},
Err(msg)=>{
println!("Error msg is {}",msg);
}
}
println!("end of main");
}
fn is_even(no:i32)->Result<bool,String> {
if no%2==0 {
return Ok(true);
} else {
return Err("NOT_AN_EVEN".to_string());
}
}
NOTE- Dal momento che le principali maniglie funzione di errore con grazia, la fine del principale dichiarazione è stampata.
Produzione
Error msg is NOT_AN_EVEN
end of main
scartare () e aspettare ()
La libreria standard contiene un paio di metodi di supporto che entrambi enumerano: Result <T, E> e Option <T> implementano. Puoi usarli per semplificare i casi di errore in cui davvero non ti aspetti che le cose falliscano. In caso di successo da un metodo, la funzione "scartare" viene utilizzata per estrarre il risultato effettivo.
Suor n | Metodo | Firma e descrizione |
---|---|---|
1 | scartare | unwrap(self): T Si aspetta che self sia Ok / Some e restituisce il valore contenuto all'interno. Se èErr o None invece, solleva il panico con il contenuto dell'errore visualizzato. |
2 | aspettarsi | expect(self, msg: &str): T Si comporta come scartare, tranne per il fatto che emette un messaggio personalizzato prima di andare nel panico oltre al contenuto dell'errore. |
scartare()
La funzione unfrap () restituisce il risultato effettivo di un'operazione riuscita. Restituisce un panico con un messaggio di errore predefinito se un'operazione non riesce. Questa funzione è un'abbreviazione per l'istruzione match. Questo è mostrato nell'esempio seguente:
fn main(){
let result = is_even(10).unwrap();
println!("result is {}",result);
println!("end of main");
}
fn is_even(no:i32)->Result<bool,String> {
if no%2==0 {
return Ok(true);
} else {
return Err("NOT_AN_EVEN".to_string());
}
}
result is true
end of main
Modificare il codice sopra per passare un numero dispari al file is_even() funzione.
La funzione Unrap () andrà in panico e restituirà un messaggio di errore predefinito come mostrato di seguito
thread 'main' panicked at 'called `Result::unwrap()` on
an `Err` value: "NOT_AN_EVEN"', libcore\result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace
aspettarsi()
Il programma può restituire un messaggio di errore personalizzato in caso di panico. Questo è mostrato nel seguente esempio:
use std::fs::File;
fn main(){
let f = File::open("pqr.txt").expect("File not able to open");
//file does not exist
println!("end of main");
}
La funzione wait () è simile a unfrap (). L'unica differenza è che un messaggio di errore personalizzato può essere visualizzato utilizzando Prevedi.
Produzione
thread 'main' panicked at 'File not able to open: Error { repr: Os
{ code: 2, message: "No such file or directory" } }', src/libcore/result.rs:860
note: Run with `RUST_BACKTRACE=1` for a backtrace.