Het gebruik van het type Result is een van de belangrijkste benaderingen voor foutafhandeling in Rust. Historisch gezien werden in veel talen - bijvoorbeeld C - fouten vaak aangegeven door speciale retourwaarden of globale variabelen, wat leidde tot veel fouten bij het negeren van deze signalen. Rust heeft gekozen voor expliciete typificatie van fouten met behulp van de enum Result<T, E>, wat het onmogelijk maakt om een fout toevallig te negeren - de compiler dwingt je om beide vertakkingen (succes en mislukking) te behandelen.
Probleem: Het was nodig om de foutafhandeling zo veilig en leesbaar mogelijk te maken, "verborgen" fouten te elimineren en de betrouwbaarheid van de code te verhogen zonder gebruik te maken van uitzonderingen.
Oplossing: Result<T, E> is een enumeratie met twee varianten: Ok(T) bij succes en Err(E) bij een fout. Dit dwingt je om fouten expliciet te behandelen of ze expliciet te negeren met behulp van unwrap of te verwachten dat panics plaatsvinden. Bovendien maakt de operator ? gangbare patronen voor het doorgeven van fouten beknopt.
Voorbeeldcode:
use std::fs::File; use std::io::{self, Read}; fn read_file(path: &str) -> Result<String, io::Error> { let mut file = File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents) }
Belangrijke kenmerken:
?.Kan de operator ? altijd worden gebruikt voor automatische foutdoorvoer naar boven?
Nee, alleen als het fouttype van de functie overeenkomt met het type van de expressie rechts van ?. Als de types niet compatibel zijn, moet je expliciet het type van de fout omzetten met de methode .map_err() of je eigen type.
Voorbeeldcode:
fn f() -> Result<(), String> { let _f = File::open("foo").map_err(|e| e.to_string())?; Ok(()) }
Kun je het resultaat van Result ongebruikt laten als je gewoon niet geïnteresseerd bent in de fouten?
Nee, de compiler geeft een waarschuwing of fout als het resultaat van het type Result niet wordt behandeld. Of je roept .unwrap() aan, of je roept expliciet .ok()/.err()/let _ = ... aan of logt de fout correct.
Wat gebeurt er als je .unwrap() aanroept op een Result met een fout?
Er zal een panic! worden aangeroepen en de uitvoering van het programma zal worden afgebroken, wat meestal leidt tot een crash. Daarom is unwrap() alleen toegestaan wanneer succes gegarandeerd is.
let _ = ...;) zonder loggingEen ontwikkelaar besloot de configuratie uit een bestand te lezen en gebruikte unwrap() op het resultaat van het lezen.
Voordelen:
Nadelen:
Fouten bij het lezen van de configuratie worden gelogd en omhoog door de oproepstack teruggegeven met behulp van Result + de operator ?.
Voordelen:
Nadelen: