Rust
Panik und Abwicklungen
Suche…
Einführung
panic!
Makro kann aufgerufen werden, um schnell zu beenden (häufig verglichen, jedoch geringfügig anders als eine Ausnahme in anderen Sprachen). Die richtige Fehlerbehandlung sollte mit Result
sein, obwohl in diesem Abschnitt nur panic!
und seine Konzepte.
Bemerkungen
Paniken verursachen nicht immer Speicherlecks oder andere Ressourcenlecks. Panics bewahren in der Regel RAII-Invarianten, indem sie die Destruktoren (Drop-Implementierungen) von Strukturen ausführen, während der Stapel abgewickelt wird. Wenn während dieses Vorgangs eine zweite Panik auftritt, bricht das Programm einfach ab. zu diesem Zeitpunkt sind die RAII-Invariantengarantien nichtig.
Versuchen Sie nicht in Panik zu geraten
In Rust gibt es zwei Hauptmethoden, um anzuzeigen, dass in einem Programm ein Fehler aufgetreten ist: Eine Funktion, die einen ( möglicherweise benutzerdefinierten ) Err(E)
, vom Typ Result<T, E>
und eine panic!
.
Panik ist keine Alternative für Ausnahmen, die häufig in anderen Sprachen zu finden sind. In Rust bedeutet Panik, dass etwas ernsthaft schiefgegangen ist und nicht fortgesetzt werden kann. Hier ist ein Beispiel aus der Vec
Quelle für 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();
}
...
}
Wenn nicht genügend Speicherplatz zur Verfügung steht, gibt es nicht viel anderes, was Rust tun kann. Daher wird entweder Panik ausgelöst (das Standardverhalten) oder der Vorgang abgebrochen (was mit einem Kompilierungsflag gesetzt werden muss).
Bei Panik wird der Stack abgewickelt, die Destruktoren ausgeführt und sichergestellt, dass der Speicher aufgeräumt wird. Abort führt dies nicht aus und setzt das Betriebssystem für eine ordnungsgemäße Bereinigung ein.
Versuchen Sie, das folgende Programm sowohl normal als auch mit auszuführen
[profile.dev]
panic = "abort"
in Ihrem 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!");
}