#error #debugging #display #print #main

main_error

在main()中使用?时,用Display代替Debug打印错误

3个版本

0.1.2 2021年9月12日
0.1.1 2020年7月18日
0.1.0 2019年9月24日

271命令行界面

Download history 999/week @ 2024-03-13 946/week @ 2024-03-20 718/week @ 2024-03-27 879/week @ 2024-04-03 776/week @ 2024-04-10 729/week @ 2024-04-17 738/week @ 2024-04-24 521/week @ 2024-05-01 566/week @ 2024-05-08 619/week @ 2024-05-15 711/week @ 2024-05-22 476/week @ 2024-05-29 516/week @ 2024-06-05 643/week @ 2024-06-12 840/week @ 2024-06-19 438/week @ 2024-06-26

2,515 每月下载量
27 个Crate(24个直接使用) 中使用

MIT 许可证

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
    1. 这允许它在任何实现了Error特质(见上面示例)的类型中使用。
    2. 它也可以替代任何可以转换Box<dyn Error>的类型,例如String
  • MainError没有实现Error特质。原因
    1. 这不是必要的,因为标准库只要求E: Debugmain() -> Result<T, E>中。
    2. 您应该只使用MainErrormain()中,而Error特质更多的是用于库之间的互操作性。
    3. 简单地不能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: " 部分来自 标准库,因此无法更改。

无运行时依赖