Rust
Panics and Unwinds
Ricerca…
introduzione
panic!
la macro può essere chiamata per uscire rapidamente (spesso confrontata, ma sottilmente diversa, con un'eccezione in altre lingue). La corretta gestione degli errori dovrebbe coinvolgere i tipi di Result
, anche se questa sezione parlerà solo di panic!
e i suoi concetti.
Osservazioni
I panici non causano sempre perdite di memoria o altre perdite di risorse. In effetti, il panico in genere conserva gli invarianti RAII, eseguendo i distruttori (implementazioni Drop) delle strutture mentre lo stack si svolge. Tuttavia, se c'è un secondo panico durante questo processo, il programma semplicemente abortisce; a quel punto, le garanzie invarianti RAII sono nulle.
Cerca di non andare nel panico
In Rust, ci sono due metodi principali per indicare che qualcosa è andato storto in un programma: una funzione che restituisce un Err(E)
potenzialmente definito dall'utente ) Err(E)
, dal tipo di Result<T, E>
e un panic!
.
Il panico non è un'alternativa per le eccezioni, che si trovano comunemente in altre lingue. In Rust, il panico è indicare che qualcosa è andato seriamente male e che non può continuare. Ecco un esempio dal sorgente Vec
per 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();
}
...
}
Se esauriamo la memoria, non c'è molto altro che Rust può fare, quindi sarà panico (il comportamento predefinito) o interromperà (che deve essere impostato con un flag di compilazione).
Il panico sbloccherà lo stack, eseguirà i distruttori e assicurerà che la memoria venga ripulita. Abort non lo fa e si affida al sistema operativo per ripulirlo correttamente.
Prova ad eseguire il seguente programma sia normalmente che con
[profile.dev]
panic = "abort"
nel tuo 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!");
}