异常处理
panic!
panic!表示程序无法从中恢复的状态。它会展开堆栈、清理资源,然后退出。这通常用于程序错误或理论上不可能达到的状态。
fn main() {
panic!("This is a panic message!"); // 主动抛出错误
}
当程序意外退出时,触发隐式 panic!,例如:
fn main() {
let v = vec![1, 2, 3];
println!("{}", v[99]); // 访问越界会触发 panic!
}
Option<T>
fn main() {
let v = vec![1, 2, 3];
// Attempt to get the element at index 1 (which is 2)
let second_element: Option<i32> = v.get(1);
match second_element {
Some(val) => println!("The second element is: {:?}", val), // Output: The second element is: 2
None => println!("There is no second element."),
}
// Attempt to get the element at index 99 (out of bounds)
let non_existent_element: Option<i32> = v.get(99);
match non_existent_element {
Some(val) => println!("The 99th element is: {:?}", val),
None => println!("Element at index 99 is: None"), // Output: Element at index 99 is: None
}
}
Result<T, E>
fn main() {
let x = 1;
let y = 0;
let q: Result<i32, String> = if y != 0 {
Ok(x / y)
} else {
Err("Division by zero encountered".to_string()) // Return a String error
};
match q {
Ok(val) => println!("{} / {} = {:?}", x, y, val),
Err(err_msg) => println!("Error during division: {}", err_msg),
// Output: Error during division: Division by zero encountered
}
}
unwrap() 和 expect() 让程序崩溃
unwrap() 让程序崩溃
unwrap()是 Option<T> 和 Result<T, E> 类型的一个方法,用于提取其中的值。
对于 Option<T>,unwrap()会返回Some(T)中的值,如果是None,则会引发panic!。
对于 Result<T, E>,unwrap()会返回Ok(T)中的值,如果是Err(E),则会引发panic!。
fn main() {
let v = vec![1, 2, 3];
let second_element = v.get(1).unwrap(); // This will succeed and return 2
println!("The second element is: {}", second_element); // Output: The second element is: 2
expect() 让程序崩溃并提供错误信息
expect()与unwrap()类似,但它允许您提供一个自定义的错误消息,当发生错误时,这个消息会被打印出来,帮助您更好地理解发生了什么问题。
fn main() {
let v = vec![1, 2, 3];
let second_element = v.get(1).expect("Failed to get the second element!"); // This will succeed and return 2
println!("The second element is: {}", second_element); // Output: The second element is: 2
let non_existent_element = v.get(99).expect("Failed to get the 99th element!"); // This will panic with the provided message
}
当尝试访问索引99时,程序会崩溃,并输出以下错误
总结
摘要:unwrap()对比expect() 两者unwrap()都expect()用于从中获取内部值,Option或者Result当您确信该值应该存在时使用。
Option如果是None或,Result他们都会惊慌失措Err。
unwrap()出现故障,并显示通用的默认消息。
expect()None它会抛出一个自定义消息,该消息由您作为参数提供,这对于精确定位意外错误或异常的来源和上下文非常有价值Err。
?运算符
?运算符是Rust中用于简化错误处理的一种语法糖。它可以用于 Result<T, E> 类型的表达式,当表达式返回Err(E)时,?运算符会立即返回该错误,而不是继续执行后续代码。这使得代码更简洁和易读。
// question.rs
#![allow(unused)] // To suppress warnings for unused code during demonstration
// Question operator - ?
fn f1() -> Result<u32, String> {
println!("f1"); // Indicates function f1 was called
Ok(1) // Successfully returns 1
}
fn f2() -> Result<u32, String> {
println!("f2"); // Indicates function f2 was called
Ok(2) // Successfully returns 2
}
// 在用?运算符之前,需要 使用match来处理每个函数的结果
fn f1_f2_match() -> Result<u32, String> {
let res_1 = f1(); // Call f1, get Result<u32, String>
let out_1 = match res_1 {
Ok(num) => num, // If Ok, extract the number
Err(_) => { // If Err
return Err("error from f1".to_string()); // Return the error immediately
}
};
let res_2 = f2(); // Call f2, get Result<u32, String>
let out_2 = match res_2 {
Ok(num) => num, // If Ok, extract the number
Err(_) => { // If Err
return Err("error from f2".to_string()); // Return the error immediately
}
};
Ok(out_1 + out_2) // If both successful, sum and return Ok(sum)
}
// 使用?运算符简化错误处理
// 正确的就继续,错误的就直接返回错误
fn f1_f2_question() -> Result<u32, String> {
let out_1 = f1()?; // Call f1. If Ok, unwrap. If Err, return Err from f1_f2_question.
let out_2 = f2()?; // Call f2. If Ok, unwrap. If Err, return Err from f1_f2_question.
Ok(out_1 + out_2) // If both successful, sum and return Ok(sum)
}