rust 错误
1 Unrecoverable Errors
越界
1.1 一些宏
fn not_yet_implemented() {
// 标记尚未实现的功能。
// 当执行到这个宏时,程序会 panic,并显示一条消息
unimplemented!();
}
fn feature_not_ready_yet() {
// 用于标记代码中的“待办事项”
// 即开发者知道这部分代码需要在未来完成
todo!("Implement this feature");
}
fn unreachable() {
// 表明某个代码路径实际上不应该被执行到
// 如果执行到这个宏,程序会触发一个 panic
unreachable!();
}
fn main() {
let x = 5;
assert!(x < 10); // 如果 x >= 10,则会 panic
let a = 5;
let b = 6;
assert_eq!(a, b); // 如果 a != b,则会 panic
assert_ne!(a, b); // 如果 a == b,则会 panic
}2 Recoverable Errors
2.1 match
use std::fs::File;
fn main() {
let greeting_file_result = File::open("hello.txt");
let greeting_file = match greeting_file_result {
Ok(file) => file, // 返回给 greeting_file
Err(error) => {
// 直接panic
panic!("Problem opening the file: {:?}", error);
}
};
}use std::fs::File;
use std::io::ErrorKind;
fn main() {
let greeting_file_result = File::open("hello.txt");
let greeting_file = match greeting_file_result {
Ok(file) => file,
Err(error) => match error.kind() {
// 匹配不同的错误
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
other_error => {
panic!("Problem opening the file: {:?}", other_error);
}
},
};
}2.2 unwrap_or_else
使用 Result<T, E> 的方法 unwrap_or_else
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let greeting_file = File::open("hello.txt").unwrap_or_else(|error| {
if error.kind() == ErrorKind::NotFound {
File::create("hello.txt").unwrap_or_else(|error| {
panic!("Problem creating the file: {:?}", error);
})
} else {
panic!("Problem opening the file: {:?}", error);
}
});
}2.3 unwrap
2.4 expect
相比unwrap 就是能定义输出的错误信息
2.5 ?
use std::fs::File;
use std::io::{self, Read};
fn main() {
read_username_from_file().unwrap();
}
fn read_username_from_file() -> Result<String, io::Error> {
let username_file_result = File::open("hello.txt");
// 错误的情况, 返回 result<String,Error>
let mut username_file = match username_file_result {
Ok(file) => file,
// return 会退出函数, 返回Err(e) 给read_username_from_file
Err(e) => return Err(e),
};
let mut username = String::new();
// 不管结果如何, 都返回 ,让给调用者处理
match username_file.read_to_string(&mut username) {
Ok(_) => Ok(username),
Err(e) => Err(e),
} // 注意这里是没有 ; 的, 因为要返回 result<T,E>
}上面的写法, 你会发现, 有同样类似的逻辑, 就是将结果result 给调用者自己处理, 使用? 简化代码
use std::fs::File;
use std::io::{self, Read};
fn main() {
read_username_from_file().unwrap();
}
fn read_username_from_file() -> Result<String, io::Error> {
// \? 放在 Result 类型的返回值上
// 如果返回值是 Ok,那么Ok包含的value 会被返回, 程序继续执行
// 如果返回值是 Err, 则 当前函数执行完毕, return Err ,Err作为函数的返回值
let mut username_file = File::open("hello.txt")?;
let mut username = String::new();
let s = username_file.read_to_string(&mut username)?;
println!("s:=={}", s); // 读取的字节书
Ok(username)
}更简洁
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
let mut username = String::new();
File::open("hello.txt")?.read_to_string(&mut username)?;
Ok(username)
}当然 标准库 提供了 上面的需求的更好的方法, 知道就行, 这不是我们讨论的点.
use std::fs;
use std::io;
fn read_username_from_file() -> Result<String, io::Error> {
fs::read_to_string("hello.txt")
}
Caution
- ? 只能被用在 函数里
- 只能用在 Result, Option, 或者其他 实现了 FromResidual的 类型上
下面代码报错了