【Rust自学】11.3. 自定义错误信息 11.3 自定义错误信息11.3.1. 添加错误信息在 11.2. 断言(Assert) 中我们学习了assert!、assert_eq!和assert_ne!这三个宏而这篇文章讲的是它们的进阶用法。这三个宏可以接收自定义错误信息但这是可选项。如果添加了自定义信息它们会和标准的失败信息一起打印出来- 对于assert!第一个参数是必填的自定义信息作为第二个参数。- 对于assert_eq!和assert_ne!前两个参数是必填的自定义信息作为第三个参数。把自定义信息传进去之后它会被传给format!宏来构建字符串。由于format!可以使用{}占位符所以传进去的信息也可以使用占位符。看个例子pub fn greeting(name: str) - String { format!(Hello {name}!) } #[cfg(test)] mod tests { use super::*; #[test] fn greeting_contains_name() { let result greeting(Carol); assert!(result.contains(Carol)); } }greeting接收一个名为name的字符串切片参数并返回由Hello、name和!拼接而成的字符串。greeting_contains_name测试函数先把greeting(Carol)的返回值赋给result然后在result上调用contains方法检查result是否包含Carol。这段代码现在可以通过测试。现在手动引入一个bug修改greeting函数pub fn greeting(name: str) - String { format!(Hello!) } #[cfg(test)] mod tests { use super::*; #[test] fn greeting_contains_name() { let result greeting(Carol); assert!(result.contains(Carol)); } }这样测试会失败$ cargo test Compiling greeter v0.1.0 (file:///projects/greeter) Finished test profile [unoptimized debuginfo] target(s) in 0.14s Running unittests src/lib.rs (target/debug/deps/greeter-647141eed08f233c) running 1 test test tests::greeting_contains_name ... FAILED failures: ---- tests::greeting_contains_name stdout ---- thread tests::greeting_contains_name (455732) panicked at src/lib.rs:12:9: assertion failed: result.contains(Carol) note: run with RUST_BACKTRACE1 environment variable to display a backtrace failures: tests::greeting_contains_name test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass --lib不过失败信息只说在第12行第9列发生了恐慌并没有提供更友好、更有用的信息。怎么办呢添加自定义信息pub fn greeting(name: str) - String { format!(Hello!) } #[cfg(test)] mod tests { use super::*; #[test] fn greeting_contains_name() { let result greeting(Carol); assert!( result.contains(Carol), Greeting did not contain name, value was {result} ); } }输出$ cargo test Compiling greeter v0.1.0 (file:///projects/greeter) Finished test profile [unoptimized debuginfo] target(s) in 0.09s Running unittests src/lib.rs (target/debug/deps/greeter-647141eed08f233c) running 1 test test tests::greeting_contains_name ... FAILED failures: ---- tests::greeting_contains_name stdout ---- thread tests::greeting_contains_name (456094) panicked at src/lib.rs:12:9: Greeting did not contain name, value was Hello! note: run with RUST_BACKTRACE1 environment variable to display a backtrace failures: tests::greeting_contains_name test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass --lib可以看到自定义信息出现在了错误输出里。这样的信息更有实际意义也更容易找出错误原因。