? 运算符与错误传播
学习目标
- 掌握
? 运算符
- 理解错误自动转换
- 掌握链式错误处理
核心概念
基本用法
use std::fs;
use std::io;
use std::num::ParseIntError;
fn read_number() -> Result<i32, io::Error> {
let content = fs::read_to_string("number.txt")?;
let number: i32 = content.trim().parse().map_err(|e: ParseIntError| {
io::Error::new(io::ErrorKind::InvalidData, e)
})?;
Ok(number)
}
fn read_number_verbose() -> Result<i32, io::Error> {
let content = match fs::read_to_string("number.txt") {
Ok(c) => c,
Err(e) => return Err(e),
};
Ok(42)
}
main 函数使用 ?
fn main() -> Result<(), Box<dyn std::error::Error>> {
let content = std::fs::read_to_string("config.txt")?;
println!("{}", content);
Ok(())
}
链式调用
use std::fs;
use std::num::ParseIntError;
fn process() -> Result<i32, Box<dyn std::error::Error>> {
let content = fs::read_to_string("data.txt")?;
let number: i32 = content.trim().parse()?;
Ok(number * 2)
}
自定义 From 实现自动转换
#[derive(Debug)]
enum MyError { Io(std::io::Error), Parse(std::num::ParseIntError) }
impl From<std::io::Error> for MyError {
fn from(e: std::io::Error) -> Self { MyError::Io(e) }
}
impl From<std::num::ParseIntError> for MyError {
fn from(e: std::num::ParseIntError) -> Self { MyError::Parse(e) }
}
fn read_number() -> Result<i32, MyError> {
let content = std::fs::read_to_string("number.txt")?;
let number: i32 = content.trim().parse()?;
Ok(number)
}
小结
| 语法 | 含义 |
|---|
expr? | 成功继续,失败返回 Err |
From< E> | 错误类型自动转换 |
Box<dyn Error> | 通用错误类型 |