Result 与 ? 运算符
传播错误
Result 与 ? 运算符 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。
Result 类型
Result<T, E> 表示一个可能成功并得到 Ok(T),也可能失败并得到 Err(E) 的操作。它是 Rust 主要的错误处理类型。
fn main() {
let parsed: Result<i32, _> = "42".parse::<i32>();
println!("{:?}", parsed);
}匹配 Result
您可以使用 match 显式处理两种结果。
fn main() {
match "oops".parse::<i32>() {
Ok(n) => println!("got {n}"),
Err(e) => println!("error: {e}"),
}
}返回 Result
可能失败的函数会返回 Result,由调用者决定如何处理错误。
fn halve(n: i32) -> Result<i32, String> {
if n % 2 == 0 {
Ok(n / 2)
} else {
Err("odd number".to_string())
}
}
fn main() {
println!("{:?}", halve(10));
println!("{:?}", halve(7));
}? 运算符
? 运算符会解包 Ok 值,或者从函数中提前返回 Err。它可以替代冗长的匹配并返回代码。
fn double_str(s: &str) -> Result<i32, std::num::ParseIntError> {
let n = s.parse::<i32>()?;
Ok(n * 2)
}
fn main() {
println!("{:?}", double_str("21"));
println!("{:?}", double_str("x"));
}使用 ? 链式处理
将多个可能失败的步骤与 ? 链接起来后,代码更清晰;第一个错误会使后续步骤立即停止。
fn sum_two(a: &str, b: &str) -> Result<i32, std::num::ParseIntError> {
let x = a.parse::<i32>()?;
let y = b.parse::<i32>()?;
Ok(x + y)
}
fn main() {
println!("{:?}", sum_two("3", "4"));
}main 中的 ?
main 可以返回 Result,因此其中也能使用 ?。返回的 Err 会以非零退出代码结束程序。
fn main() -> Result<(), std::num::ParseIntError> {
let n: i32 = "100".parse()?;
println!("parsed {n}");
Ok(())
}实用的 Result 方法
实用的组合方法:
unwrap_or(default)——返回值或备用值map——转换 Ok 值map_err——转换错误is_ok/is_err——检查变体
fn main() {
let n = "x".parse::<i32>().unwrap_or(-1);
println!("{n}");
}将 Option 转换为 Result
使用 ok_or 将 Option 转换为 Result,这样 ? 就能传播有意义的错误。
fn first_char(s: &str) -> Result<char, String> {
let c = s.chars().next().ok_or("empty string".to_string())?;
Ok(c)
}
fn main() {
println!("{:?}", first_char("hi"));
println!("{:?}", first_char(""));
}? 如何转换错误
当错误类型不同时,? 会调用 From::from,将错误转换为函数声明的错误类型。这使跨层进行错误处理更加便捷。
在生产代码中避免使用 unwrap
unwrap 和 expect 遇到 Err 时会引发 panic。它们适合示例和测试,但在实际代码中应优先使用 ? 或显式处理,以便错误能够恢复。
使用 and_then 链式处理
只有前一步成功时,and_then 才会运行下一步可能失败的操作,并将值继续传递下去。
fn main() {
let result = "8"
.parse::<i32>()
.and_then(|n| Ok(n * 2));
println!("{:?}", result);
}快速检查
对一个值为 Err 的 Result 使用 ? 运算符时,会发生什么?
回顾
您已经学习了基于 Result 的错误处理:
Result<T, E>表示成功或失败?会解包 Ok,或提前返回 Err?可用于返回 Result 的函数和mainmap、map_err、unwrap_or和ok_or等组合器都很有帮助- 在生产环境中应避免使用
unwrap
常见问题解答
「Result 与 ? 运算符」课时是免费的吗?
是的 — 「Result 与 ? 运算符」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。
「Result 与 ? 运算符」这节课中我会学到什么?
传播错误 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn Rust Coding 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「Result 与 ? 运算符」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn Rust Coding 课中编写并运行代码吗?
能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。