Ricerca…


introduzione

Quando i programmi Rust raggiungono uno stato in cui si è verificato un errore critico, il 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!");
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow