Rost - Fehlerbehandlung

In Rust können Fehler in zwei Hauptkategorien eingeteilt werden, wie in der folgenden Tabelle gezeigt.

Sr.Nr. Name & Beschreibung Verwendung
1

Recoverable

Fehler, die behandelt werden können

Ergebnisaufzählung
2

UnRecoverable

Fehler, die nicht behandelt werden können

Panikmakro

Ein behebbarer Fehler ist ein Fehler, der behoben werden kann. Ein Programm kann den fehlgeschlagenen Vorgang wiederholen oder eine alternative Vorgehensweise angeben, wenn ein behebbarer Fehler auftritt. Behebbare Fehler führen nicht dazu, dass ein Programm abrupt fehlschlägt. Ein Beispiel für einen behebbaren Fehler ist der Fehler " Datei nicht gefunden" .

Nicht behebbare Fehler führen dazu, dass ein Programm abrupt fehlschlägt. Ein Programm kann nicht in den Normalzustand zurückkehren, wenn ein nicht behebbarer Fehler auftritt. Der fehlgeschlagene Vorgang kann nicht wiederholt oder der Fehler rückgängig gemacht werden. Ein Beispiel für einen nicht behebbaren Fehler ist der Versuch, auf einen Speicherort jenseits des Endes eines Arrays zuzugreifen.

Im Gegensatz zu anderen Programmiersprachen hat Rust keine Ausnahmen. Es gibt ein Enum- Ergebnis <T, E> für behebbare Fehler zurück, während es das aufruftpanicMakro, wenn das Programm auf einen nicht behebbaren Fehler stößt. Die Panik Makro bewirkt , dass das Programm abrupt zu verlassen.

Panikmakro und nicht behebbare Fehler

Panik! Mit dem Makro kann ein Programm sofort beendet und dem Aufrufer des Programms eine Rückmeldung gegeben werden. Es sollte verwendet werden, wenn ein Programm einen nicht wiederherstellbaren Zustand erreicht.

fn main() {
   panic!("Hello");
   println!("End of main"); //unreachable statement
}

Im obigen Beispiel wird das Programm sofort beendet, wenn es auf Panik stößt ! Makro.

Ausgabe

thread 'main' panicked at 'Hello', main.rs:3

Illustration: Panik! Makro

fn main() {
   let a = [10,20,30];
   a[10]; //invokes a panic since index 10 cannot be reached
}

Die Ausgabe ist wie unten gezeigt -

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.

Ein Programm kann die Panik auslösen! Makro, wenn Geschäftsregeln verletzt werden, wie im folgenden Beispiel gezeigt -

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");
}

Das obige Beispiel gibt einen Fehler zurück, wenn der der Variablen zugewiesene Wert ungerade ist.

Ausgabe

thread 'main' panicked at 'NOT_AN_EVEN', main.rs:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Ergebnisaufzählung und behebbare Fehler

Aufzählungsergebnis - <T, E> kann verwendet werden, um behebbare Fehler zu behandeln. Es hat zwei Varianten -OK und Err. T und E sind generische Typparameter. T stellt den Typ des Werts dar, der in einem Erfolgsfall innerhalb der OK-Variante zurückgegeben wird, und E stellt den Typ des Fehlers dar, der in einem Fehlerfall innerhalb der Err-Variante zurückgegeben wird.

enum Result<T,E> {
   OK(T),
   Err(E)
}

Lassen Sie uns dies anhand eines Beispiels verstehen -

use std::fs::File;
fn main() {
   let f = File::open("main.jpg"); 
   //this file does not exist
   println!("{:?}",f);
}

Das Programm gibt OK (Datei) zurück, wenn die Datei bereits vorhanden ist, und Err (Fehler), wenn die Datei nicht gefunden wird.

Err(Error { repr: Os { code: 2, message: "No such file or directory" } })

Lassen Sie uns nun sehen, wie mit der Err-Variante umgegangen wird.

Das folgende Beispiel behandelt einen Fehler, der beim Öffnen der Datei mit dem zurückgegeben wird match Erklärung

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- Das Programm druckt am Ende des Hauptereignisses obwohl Datei wurde nicht gefunden. Dies bedeutet, dass das Programm Fehler ordnungsgemäß behandelt hat.

Ausgabe

file not found
Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
end of main

Illustration

Die Funktion is_even gibt einen Fehler zurück, wenn die Zahl keine gerade Zahl ist. Die Funktion main () behandelt diesen Fehler.

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- Da die Hauptfunktion Fehler ordnungsgemäß behandelt, wird das Ende der Hauptanweisung gedruckt.

Ausgabe

Error msg is NOT_AN_EVEN
end of main

auspacken () und erwarten ()

Die Standardbibliothek enthält einige Hilfsmethoden, die beide Aufzählungen - Ergebnis <T, E> und Option <T> - implementieren. Sie können sie verwenden, um Fehlerfälle zu vereinfachen, in denen Sie wirklich nicht erwarten, dass etwas fehlschlägt. Bei Erfolg einer Methode wird die Funktion "Unwrap" verwendet, um das tatsächliche Ergebnis zu extrahieren.

Sr.Nr. Methode Unterschrift & Beschreibung
1 auspacken

unwrap(self): T

Erwartet, dass self Ok / Some ist, und gibt den darin enthaltenen Wert zurück. Wenn jaErr oder None Stattdessen wird eine Panik ausgelöst, wenn der Inhalt des Fehlers angezeigt wird.

2 erwarten von

expect(self, msg: &str): T

Verhält sich wie Auspacken, außer dass zusätzlich zum Inhalt des Fehlers eine benutzerdefinierte Nachricht ausgegeben wird, bevor in Panik geraten wird.

auspacken()

Die Funktion unwrap () gibt das tatsächliche Ergebnis zurück, mit dem eine Operation erfolgreich ist. Es wird eine Panik mit einer Standardfehlermeldung zurückgegeben, wenn ein Vorgang fehlschlägt. Diese Funktion ist eine Abkürzung für Match-Anweisung. Dies wird im folgenden Beispiel gezeigt -

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

Ändern Sie den obigen Code, um eine ungerade Zahl an die zu übergeben is_even() Funktion.

Die Funktion unwrap () gerät in Panik und gibt eine Standardfehlermeldung zurück, wie unten gezeigt

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

erwarten von()

Das Programm kann im Falle einer Panik eine benutzerdefinierte Fehlermeldung zurückgeben. Dies wird im folgenden Beispiel gezeigt -

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");
}

Die Funktion require () ähnelt unwrap (). Der einzige Unterschied besteht darin, dass eine benutzerdefinierte Fehlermeldung mit "Expect" angezeigt werden kann.

Ausgabe

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.