rust / intermediate
Snippet
Panik-Wiederherstellung mit catch_unwind
Die catch_unwind-Funktion ermöglicht Wiederherstellung von Panics, indem sie Closure-Ausführung kapselt und Results zurückgibt, wobei Ok das normale Ergebnis enthält oder Err die Panic-Nutzlast. AssertUnwindSafe ist ein Marker-Trait, das anzeigt, dass die Closure keine Ressourcen enthält, die deterministische Bereinigung durch Drop benötigen. Wenn eine Panic auftritt, führt Rust weiterhin Destruktoren für Drop-Typen während des Entladens aus, aber catch_unwind verhindert, dass die Panic zum aufrufenden Thread propagiert. Dies ist wertvoll zum Isolieren gefährlichen Codes in Tests oder Server-Anfragsverarbeitung.
snippet.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use std::panic::{catch_unwind, AssertUnwindSafe};fn risky_operation(input: i32) -> Result<i32, String> {if input < 0 {panic!("Negative input not allowed: {}", input);}Ok(input * 2)}fn safe_wrapper() {let result = catch_unwind(AssertUnwindSafe(|| {risky_operation(-5)}));match result {Ok(Ok(value)) => println!("Success: {}", value),Ok(Err(msg)) => println!("Logic error: {}", msg),Err(_) => println!("Panic was caught!"),}}struct Resource {data: String,}impl Drop for Resource {fn drop(&mut self) {println!("Cleaning up: {}", self.data);}}fn with_cleanup() {let result = catch_unwind(AssertUnwindSafe(|| {let resource = Resource { data: String::from("allocated") };panic!("Simulated failure");}));if result.is_err() {println!("Panic caught, destructor still ran");}}fn main() {safe_wrapper();with_cleanup();}
Erklärung
1
catch_unwind(AssertUnwindSafe(||
Wrapper für wiederherstellbare Panic-Erkennung
2
Ok(Ok(value))
Dreifach verschachtelt: keine Panic, kein Fehler, enthält Wert
3
Err(_) => println!("Panic war gefangen!")
Panic-Nutzlast gefangen, Thread fährt fort
4
struct Resource impl Drop
Destruktor-Garantie auch während Panic-Entladung
5
result.is_err()
Prüfen ob Panic auftrat ohne Nutzlast zu lesen