结论:Result<T, E> 枚举(Ok(T) / Err(E))把可恢复错误放进返回值类型,强制调用方处理;? 运算符是传播错误的语法糖——结果是 Ok 就取出值继续,是 Err 就提前 return Err(...)(并经由 From 自动转换错误类型)。
展开:? 只能用在返回 Result(或 Option 等实现了对应 trait 的类型)的函数里。它让错误处理既显式又不啰嗦:错误路径在类型签名里可见,正常路径代码保持线性。与 panic 的分工:Result 用于预期内的失败(IO、解析),panic! 用于不可恢复的逻辑错误和不变量破坏。
use std::fs;
fn read_port() -> Result<u16, Box<dyn std::error::Error>> {
let s = fs::read_to_string("port.txt")?; // io::Error → 自动转换
let port: u16 = s.trim().parse()?; // ParseIntError → 自动转换
Ok(port)
}
易错点:main 函数也可以返回 Result<(), E: Debug> 从而使用 ?;错误类型转换依赖 impl From<E1> for E2,thiserror 的 #[from] 可自动生成。追问方向:错误类型该如何设计(库用具体枚举、应用用 anyhow)、? 的 desugar 过程。