Rust中的错误处理
Result枚举
Rust 中没有提供类似于 Java、C++ 中的 Exception 机制,而是使用 Result
枚举的方式来实现:
pub enum Result<T, E> {
/// Contains the success value
Ok(T),
/// Contains the error value
Err(E),
}
在使用时:
如果无错误则使用
Ok(T)
返回;如果存在错误,则使用
Err(E)
包装错误类型返回;
例如:
examples/0_result.rs
#[derive(Debug)]
pub enum MyError {
Internal(String),
InvalidId(String),
}
fn add(num: i64) -> Result<i64, MyError> {
if num < 0 {
Err(MyError::InvalidId(String::from("Invalid num!")))
} else {
Ok(num + 100000)
}
}
fn main() -> Result<(), MyError> {
// fetch_id(-1)?;
let res = add(1)?;
println!("{}", res);
Ok(())
}
上面的代码首先通过 MyError 枚举定义了多个可能会出现的错误;
随后,在 add
函数中:
当 num 小于 0 时返回错误;
否则给 num 增加 100000 并返回;
在上面的 let res = add(1)?;
中使用了 ?
操作符,他相当于是一个语法糖:
如果被调函数正常返回则调用
unwrap
获取其值;反之,则将被调函数的错误直接向上返回(相当于直接 return Err);
即上面的语法糖相当于:
let res = match add() {
Ok(id) => id,
Err(err) => {
return Err(err);
}
};
错误类型转换
上面简单展示了 Rust 中错误的使用;
由于 Rust 是强类型的语言,因此如果在一个函数中使用 ?
返回了多个错误,并且他们的类型是不同的,还需要对返回的错误类型进行转换,转为相同的类型!
例如下面的例子:
#[derive(Debug)]
pub enum MyError {
ReadError(String),
ParseError(String),
}
fn read_file() -> Result<i64, MyError> {
// Error: Could not get compiled!
let content = fs::read_to_string("/tmp/id")?;
let id = content.parse::<i64>()?;
}
fn main() -> Result<(), MyError> {
let id = read_file()?;
println!("id: {}", id)