核心宏
这一节我们来看看 anyhow 提供的三个核心宏:anyhow!、bail! 和 ensure!。
它们的作用是让你在代码中产生错误时,写起来像 println! 一样爽快。
1、anyhow!:快速创建错误对象
有时候你需要手动创建一个错误,而不是从别的函数传过来。anyhow! 支持字符串格式化,生成的类型是 anyhow::Error。
use anyhow::{anyhow, Result};
fn get_username(id: u32) -> Result<String> {
if id == 404 {
// 创建一个一次性的、没有特定类型的错误
return Err(anyhow!("找不到 ID 为 {} 的用户", id));
}
Ok("Alice".to_string())
}
2、bail!:错误处理的“提前离场”
bail! 是 return Err(anyhow!(...)) 的缩写。它是代码中最常用的宏,用于在检测到异常时立即退出当前函数。
对比效果:
- 普通写法:
return Err(anyhow!("权限不足")); - 使用
bail!:bail!("权限不足");
use anyhow::{bail, Result};
fn login(password: &str) -> Result<()> {
if password != "123456" {
bail!("密码错误,登录失败!"); // 简洁明了
}
println!("登录成功");
Ok(())
}
3、ensure!:带条件的错误拦截
ensure! 就像是 assert!(断言)的温和版本。
assert!:如果条件不成立,程序直接 Panic(崩溃)。ensure!:如果条件不成立,函数 返回 Err(优雅退出)。
它非常适合用来做输入校验。
use anyhow::{ensure, Result};
fn set_age(age: u8) -> Result<()> {
// 如果 age <= 150 不成立,则返回 Err
ensure!(age <= 150, "年龄 {} 显然不合逻辑", age);
println!("年龄设置为: {}", age);
Ok(())
}
4、这三个宏该选哪个?
为了帮你快速决策,可以参考下面这个简单的逻辑流:
- 只是想造个错误传给别人? → 用
anyhow!。 - 遇到错误想直接返回中止函数? → 用
bail!。 - 检查一个条件,如果不满足就返回错误? → 用
ensure!。
5、小结
| 宏 | 类似的标准宏 | 返回值 | 语义 |
|---|---|---|---|
anyhow! | format! | anyhow::Error | 创建一个错误。 |
bail! | panic! | Result<_, Error> | 立即报错退出。 |
ensure! | assert! | Result<_, Error> | 满足条件继续,否则报错。 |
提示: > 所有的宏都支持类似
println!的参数格式化,比如bail!("错误码: {}", code),非常方便。