Rust
Panique et Déroulement
Recherche…
Introduction
panic!
la macro peut être appelée pour sortir rapidement (souvent comparée, mais subtilement différente, à une exception dans d'autres langues). Une gestion correcte des erreurs devrait impliquer les types de Result
, bien que cette section ne traite que de la panic!
et ses concepts.
Remarques
Les paniques ne provoquent pas toujours des fuites de mémoire ou d'autres fuites de ressources. En fait, les paniques conservent généralement les invariants RAII, exécutant les destructeurs (implémentations Drop) des structures à mesure que la pile se déroule. Cependant, s'il y a une seconde panique au cours de ce processus, le programme abandonne simplement; à ce stade, les garanties invariantes RAII sont nulles.
Essayez de ne pas paniquer
Dans Rust, il existe deux méthodes principales pour indiquer que quelque chose a mal tourné dans un programme: Une fonction renvoyant un Err(E)
( potentiellement personnalisé Err(E)
, du type Result<T, E>
et une panic!
.
La panique n'est pas une alternative pour les exceptions, que l'on trouve couramment dans d'autres langues. Dans Rust, la panique est d’indiquer que quelque chose a vraiment mal tourné et que cela ne peut pas continuer. Voici un exemple de la source de Vec
pour 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();
}
...
}
Si nous manquons de mémoire, il n'y a pas grand-chose d'autre que Rust puisse faire, donc il va paniquer (comportement par défaut) ou abandonner (ce qui doit être défini avec un indicateur de compilation).
La panique va dérouler la pile, exécuter des destructeurs et s'assurer que la mémoire est nettoyée. Abandonner ne le fait pas, et repose sur le système d'exploitation pour le nettoyer correctement.
Essayez d'exécuter le programme suivant normalement et avec
[profile.dev]
panic = "abort"
dans votre 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!");
}