Rust
Panika i wiatr
Szukaj…
Wprowadzenie
panic!
makro można wywołać w celu szybkiego wyjścia (często porównywane, ale subtelnie różne, z wyjątkiem w innych językach). Prawidłowa obsługa błędów powinna obejmować typy Result
, chociaż w tej sekcji omówiona zostanie tylko panic!
i jego koncepcje.
Uwagi
Panika nie zawsze powoduje wycieki pamięci lub inne wycieki zasobów. W rzeczywistości, paniki zazwyczaj zachowują niezmienniki RAII, uruchamiając niszczyciele (implementacje Drop) struktur, gdy stos się rozwija. Jeśli jednak podczas tego procesu nastąpi druga panika, program po prostu przerywa; w tym momencie niezmienne gwarancje RAII są nieważne.
Staraj się nie panikować
W Rust istnieją dwie główne metody wskazywania, że coś poszło nie tak w programie: funkcja zwracająca ( potencjalnie zdefiniowane przez użytkownika ) Err(E)
z typu Result<T, E>
i panic!
.
Panikowanie nie jest alternatywą dla wyjątków, które często występują w innych językach. W Rust panika oznacza, że coś poszło nie tak i że nie można jej kontynuować. Oto przykład ze źródła Vec
dla push
:
pub fn push(&mut self, value: T) {
// This will panic or abort if we would allocate > isize::MAX bytes
// or if the length increment would overflow for zero-sized types.
if self.len == self.buf.cap() {
self.buf.double();
}
...
}
Jeśli zabraknie nam pamięci, Rust nie ma wiele więcej do roboty, więc albo wpadnie w panikę (zachowanie domyślne), albo przerwie (co należy ustawić za pomocą flagi kompilacji).
Panikowanie rozwinie stos, uruchomi destruktory i zapewni wyczyszczenie pamięci. Przerwij nie robi tego i polega na systemie operacyjnym, aby poprawnie wyczyścić.
Spróbuj uruchomić następujący program zarówno normalnie, jak i przy pomocy
[profile.dev]
panic = "abort"
w twoim Cargo.toml
.
// main.rs
struct Foo(i32);
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping {:?}!", self.0);
}
}
fn main() {
let foo = Foo(1);
panic!("Aaaaaaahhhhh!");
}