【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`

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

相关推荐
练习时长一年2 分钟前
搭建langchain4j+SpringBoot的Ai项目
java·spring boot·后端
bobz9652 分钟前
Proxmox qemu-server
后端
zhangfeng11334 分钟前
在 R 语言里,`$` 只有一个作用 按名字提取“列表型”对象里的单个元素 对象 $ 名字
开发语言·windows·r语言
文弱书生65621 分钟前
5.后台运行设置和包设计与实现
服务器·开发语言·c#
编码浪子25 分钟前
趣味学RUST基础篇(异步补充)
开发语言·后端·rust
烈风28 分钟前
003 cargo使用
rust·cargo
songroom32 分钟前
Rust : 关于Deref
开发语言·后端·rust
qq_4017004134 分钟前
QT子线程与GUI线程安全交互
开发语言·qt
高-老师39 分钟前
R语言生物群落(生态)数据统计分析与绘图实践技术应用
开发语言·r语言·生物群落
bobz96539 分钟前
对比 qemu 分析 rust vmm 的成熟度
后端