Czytam dokumentację dlaFile
:
//..
let mut file = File::create("foo.txt")?;
//..
Co jest ?
w tej linii? Nie przypominam sobie, bym widział to wcześniej w Księdze Rdzy.
Czytam dokumentację dlaFile
:
//..
let mut file = File::create("foo.txt")?;
//..
Co jest ?
w tej linii? Nie przypominam sobie, bym widział to wcześniej w Księdze Rdzy.
Odpowiedzi:
Jak być może zauważyłeś, Rust nie ma wyjątków. Występują paniki, ale ich funkcjonalność jest ograniczona (nie mogą przenosić ustrukturyzowanych informacji), a ich użycie do obsługi błędów jest odradzane (są one przeznaczone do błędów nieodwracalnych).
W Rust do obsługi błędów używa się plików Result
. Typowy przykład to:
fn halves_if_even(i: i32) -> Result<i32, Error> {
if i % 2 == 0 {
Ok(i / 2)
} else {
Err(/* something */)
}
}
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = match halves_if_even(i) {
Ok(i) => i,
Err(e) => return Err(e),
};
// use `i`
}
To jest świetne, ponieważ:
Jest jednak mniej niż idealny, ponieważ jest bardzo rozwlekły. Tutaj pojawia się operator znaku zapytania ?
.
Powyższe można przepisać jako:
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
co jest o wiele bardziej zwięzłe.
To, ?
co tutaj robi, jest równoważne z match
powyższym stwierdzeniem. W skrócie: rozpakowuje Result
if OK i zwraca błąd, jeśli nie.
To trochę magiczne, ale obsługa błędów wymaga pewnej magii, aby zmniejszyć schemat, iw przeciwieństwie do wyjątków od razu widać, które wywołania funkcji mogą, a nie muszą, zawierać błędy: te, które są ozdobione ?
.
Jednym z przykładów magii jest to, że działa to również w przypadku Option
:
// Assume
// fn halves_if_even(i: i32) -> Option<i32>
fn do_the_thing(i: i32) -> Option<i32> {
let i = halves_if_even(i)?;
// use `i`
}
Jest to zasilane przez (niestabilną) Try
cechę.
Zobacz też:
Result
lub Option
.
Służy do propagacji błędu dla naprawialnego błędu typu Wynik <T, E>. Rozpakowuje wynik i podaje wartość wewnętrzną.
Zamiast obsługiwać przypadki błędu, propagujesz je do kodu wywołującego i zajmujesz się tylko przypadkiem OK. Zaletą jest to, że eliminuje wiele schematów i upraszcza implementację funkcji.
.unwrap()
paniką w przypadku błędu.