rust / intermediate
Snippet
Panic Behandlung mit std::panic::catch_unwind
catch_unwind fängt Panics ab und konvertiert sie in Result-Werte, was Wiederherstellung aus Panic-Zuständen ermöglicht. Dies ist essentiell beim Implementieren von Plugins, Foreign Function Interfaces oder async Runtimes. AssertUnwindSafe ist ein Helfer für Closures, bei denen der Programmierer garantiert, dass sie sicher unwinden können.
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(divisor: i32) -> i32 {100 / divisor // Will panic if divisor is 0}fn main() {// Successful caselet result = catch_unwind(|| {risky_operation(10)});match result {Ok(value) => println!("Calculation succeeded: {}", value),Err(e) => println!("Panic occurred: {:?}", e),}// Panic case - divisor is 0let panic_result = catch_unwind(|| {risky_operation(0)});if panic_result.is_err() {println!("Caught panic from division by zero!");}// Using AssertUnwindSafe for shared referenceslet shared_data = vec![1, 2, 3];let safe_result = catch_unwind(AssertUnwindSafe(|| {println!("Processing: {:?}", shared_data);42}));println!("Safe result: {:?}", safe_result);// Practical example: recoverable parsinglet numbers = vec!["10", "20", "oops", "40"];for num_str in numbers {let parsed = catch_unwind(|| num_str.parse::<i32>().unwrap());match parsed {Ok(n) => println!("Parsed: {}", n),Err(_) => println!("Failed to parse '{}', continuing...", num_str),}}}
Erklärung
1
catch_unwind(|| risky_operation(10))
Führt Closure aus und fängt Panics ab, gibt Result<T, Box<dyn Any + Send>> zurück
2
AssertUnwindSafe(|| ... )
Marker-Typ, der garantiert dass Closure sicher unwinden kann - verwende wenn du weißt dass die Closure keine Invarianten verletzt
3
Ok(value) => println!("{}", value)
Normale Beendigung - kein Panic in der Closure aufgetreten
4
Err(e) => println!("{:?}", e)
Panic wurde gefangen - e enthält Panic-Payload-Informationen