【Rust自学】11.3. 自定义错误信息

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

11.3.1. 添加错误信息

在 11.2. 断言(Assert) 中我们学习了assert!assert_eq!assert_ne!这三个宏,而这篇文章讲的就是它的进阶用法。

这三个宏是可以添加自定义错误信息的,但这是可选项。如果你添加了自定义信息,那么它们将会和标准的示范信息一同打印出来:

  • 对于assert!,第一个参数是必填的,自定义信息作为第二个参数
  • 对于assert_eq!assert_ne!,前两个参数是必填的,自定义信息作为第三个参数

再把自定义信息传进去之后,这个参数会被传递给format!宏,用于拼接字符串,由于format!宏可以使用{}占位符,所以传进去的信息也可以使用占位符。

看个例子:

rust 复制代码
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,传进去之后会返回Helloname!拼在一起的字符串。
  • 下面的greeting_contains_name测试函数先给把调用greeting("Carol")所获的值赋给result,然后再在result上调用contains这个方法来查找result里是否有"Carol"

这个代码现在测试是没有问题的。

那来手动引入一个bug,修改greeting函数:

rust 复制代码
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.91s
     Running unittests src/lib.rs (target/debug/deps/greeter-170b942eb5bf5e3a)

running 1 test
test tests::greeting_contains_name ... FAILED

failures:

---- tests::greeting_contains_name stdout ----
thread 'tests::greeting_contains_name' panicked at src/lib.rs:12:9:
assertion failed: result.contains("Carol")
note: run with `RUST_BACKTRACE=1` 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个字符恐慌了,它没能提供更友好更有价值的一些信息,那怎么办呢?添加自定义信息呗:

rust 复制代码
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.93s
     Running unittests src/lib.rs (target/debug/deps/greeter-170b942eb5bf5e3a)

running 1 test
test tests::greeting_contains_name ... FAILED

failures:

---- tests::greeting_contains_name stdout ----
thread 'tests::greeting_contains_name' panicked at src/lib.rs:12:9:
Greeting did not contain name, value was `Hello!`
note: run with `RUST_BACKTRACE=1` 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`

可以看到,自定义信息出现在报错信息里了。这样的错误信息更具有实际意义,也就可以更容易地找到错误出现的原因。

相关推荐
cch89186 小时前
汇编与Java:底层与高层的编程对决
java·开发语言·汇编
荒川之神7 小时前
拉链表概念与基本设计
java·开发语言·数据库
chushiyunen7 小时前
python中的@Property和@Setter
java·开发语言·python
2401_895521347 小时前
SpringBoot Maven快速上手
spring boot·后端·maven
小樱花的樱花7 小时前
C++ new和delete用法详解
linux·开发语言·c++
froginwe117 小时前
C 运算符
开发语言
disgare8 小时前
关于 spring 工程中添加 traceID 实践
java·后端·spring
ictI CABL8 小时前
Spring Boot与MyBatis
spring boot·后端·mybatis
fengfuyao9858 小时前
低数据极限下模型预测控制的非线性动力学的稀疏识别 MATLAB实现
开发语言·matlab
摇滚侠8 小时前
搭建前端开发环境 安装 nodejs 设置淘宝镜像 最简化最标准版本 不使用 NVM NVM 高版本无法安装低版本 nodejs
java·开发语言·node.js