3个版本
| 0.1.2 | 2021年9月12日 |
|---|---|
| 0.1.1 | 2020年7月18日 |
| 0.1.0 | 2019年9月24日 |
271 在 命令行界面
2,515 每月下载量
在 27 个Crate(24个直接使用) 中使用
9KB
main_error
在main()中使用?时,用Display代替Debug打印错误。例如
use main_error::MainError;
fn main() -> Result<(), MainError> {
// This prints
// "Error: invalid digit found in string"
// instead of (if you used `Result<(), Box<dyn Error>>` or similar)
// "ParseIntError { kind: InvalidDigit }".
let number: i32 = "not a number".parse()?;
Ok(())
}
更多信息请参见
lib.rs:
在main()中使用Display代替Debug打印错误。
通过从main函数返回MainError作为错误类型来使用。示例
use main_error::MainError;
fn main() -> Result<(), MainError> {
// This prints
// "Error: invalid digit found in string"
// instead of (if you used `Result<(), Box<dyn Error>>` or similar)
// "ParseIntError { kind: InvalidDigit }".
let number: i32 = "not a number".parse()?;
Ok(())
}
为了方便,您还可以使用MainResult类型。下面将提供更多详细信息。
问题
自Rust 1.26以来,main函数可以返回一个Result<T, E>。这使您可以在小型程序和快速示例中使用?进行方便的错误处理(RFC)。
不幸的是,错误是通过Debug(在标准库中硬编码,搜索"Error:")打印的,这给出了不太美观或不友好的输出。
例如,这个程序
fn main() -> Result<(), ParseIntError> {
let num: i32 = "not a number".parse()?;
// ...
}
将打印
Error: ParseIntError { kind: InvalidDigit }
解决方案
此库提供MainError,作为您main函数中错误类型E的即插即用替换。它通过Display而不是Debug打印错误,从而生成更友好的错误信息。例如,上面的程序可以改为
use main_error::MainError;
fn main() -> Result<(), MainError> {
let _: i32 = "not a number".parse()?;
// ...
}
现在打印
Error: invalid digit found in string
细节和缺点
MainError将原始错误存储为Box<dyn Error>。这会产生一次分配(在转换时)和一次虚拟调用(在打印时)。由于在程序结束之前,这样的错误恰好只有一个,因此这种成本是微不足道的。MainError为所有可以转换为Box<dyn Error>的类型实现了From。- 这允许它在任何实现了
Error特质(见上面示例)的类型中使用。 - 它也可以替代任何可以转换为
Box<dyn Error>的类型,例如String。
- 这允许它在任何实现了
MainError没有实现Error特质。原因- 这不是必要的,因为标准库只要求
E: Debug在main() -> Result<T, E>中。 - 您应该只使用
MainError在main()中,而Error特质更多的是用于库之间的互操作性。 - 简单地不能为
MainError实现Error,因为这会创建一个重叠的impl。
解释MainError可以从一个T: Into<Box<dyn Error>>转换。Into<Box<dyn Error>>为E: Error本身实现。- 如果
MainError实现了Error,它可以从自己转换。 - 这与核心中的 自反的
impl<T> From<T> for T冲突。。
- 这不是必要的,因为标准库只要求
MainError通过底层的错误Display实现了Debug。这是一个巧妙的做法,但遗憾的是Debug作为输出现在稳定了。输出开头的"Error: "部分来自 标准库,因此无法更改。