【Rust自学】11.4. 用should_panic检查恐慌
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

11.4.1. 验证错误处理的情况
测试函数出了验证代码的返回值是否正确,还需要验证代码是否如预期的去处理了发生错误的情况。比如说可以编写一个测试来验证代码是否在特定情况下发生了panic!。
这种测试需要为函数额外增加should_panic属性。使用它标记的函数,如果在函数内发生了恐慌,则代表通过测试;反之就失败。
看个例子:
pub struct Guess {value: i32,
}impl Guess {pub fn new(value: i32) -> Guess {if value < 1 || value > 100 {panic!("Guess value must be between 1 and 100, got {value}.");}Guess { value }}
}#[cfg(test)]
mod tests {use super::*;#[test]#[should_panic]fn greater_than_100() {Guess::new(200);}
}
- 结构体
Guess有一个存储u32类型数据的字段value,它有一个关联函数new用于创建一个Guess实例,但前提是传进new的参数大于1小于100,否则就要恐慌。 greater_than_100这个测试函数测试给new函数传入大于100的值,这时候应该发生恐慌,所以为这个测试函数添加了一个should_panic的attribute(属性),也就是写#[should_panic]。
测试结果:
$ cargo testCompiling guessing_game v0.1.0 (file:///projects/guessing_game)Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58sRunning unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d)running 1 test
test tests::greater_than_100 - should panic ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sDoc-tests guessing_gamerunning 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
下面来人为引入bug,把new函数里的value > 100的判断去掉:
pub struct Guess {value: i32,
}impl Guess {pub fn new(value: i32) -> Guess {if value < 1 || value > 100 {panic!("Guess value must be between 1 and 100, got {value}.");}Guess { value }}
}#[cfg(test)]
mod tests {use super::*;#[test]#[should_panic]fn greater_than_100() {Guess::new(200);}
}
这时候测试函数中的Guess::new(200);就不会恐慌,但是因为它添加了should_panic这个attribute,所以本应该恐慌的函数没有恐慌就会导致测试失败:
$ cargo testCompiling guessing_game v0.1.0 (file:///projects/guessing_game)Finished `test` profile [unoptimized + debuginfo] target(s) in 0.62sRunning unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d)running 1 test
test tests::greater_than_100 - should panic ... FAILEDfailures:---- tests::greater_than_100 stdout ----
note: test did not panic as expectedfailures:tests::greater_than_100test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00serror: test failed, to rerun pass `--lib`
11.4.2. 让should_panic更精确
有的时候使用should_panic进行的测试会有点含糊不清,因为它仅仅能够说明被检查的代码是否发生了恐慌,即使这个恐慌和程序员预期的恐慌不一样。
为了使测试更精确,可以为should_panic添加一个可选的expected参数。这样程序就会检查失败消息中是否包含所指定的文字。
看个例子:
pub struct Guess {value: i32,
}impl Guess {pub fn new(value: i32) -> Guess {if value < 1 {panic!("Guess value must be greater than or equal to 1, got {value}.");} else if value > 100 {panic!("Guess value must be less than or equal to 100, got {value}.");}Guess { value }}
}#[cfg(test)]
mod tests {use super::*;#[test]#[should_panic(expected = "less than or equal to 100")]fn greater_than_100() {Guess::new(200);}
}
- 在刚才的结构体上稍微进行了修改,把
new函数里value < 1和value > 100的情况分开写了两个不同的恐慌信息。 - 给
should_panic属性添加了expected参数,=后面跟的就是期待的报错信息。只有测试函数恐慌并且恐慌信息包括期待的报错信息才算测试成功,否则就算失败。
这个程序肯定能成功。
一样的套路,我们来手动引入错误,比如我们把new函数里小于1和大于100的恐慌信息交换一下:
pub struct Guess {value: i32,
}impl Guess {pub fn new(value: i32) -> Guess {if value < 1 {panic!("Guess value must be less than or equal to 100, got {value}.");} else if value > 100 {panic!("Guess value must be greater than or equal to 1, got {value}.");}Guess { value }}
}#[cfg(test)]
mod tests {use super::*;#[test]#[should_panic(expected = "less than or equal to 100")]fn greater_than_100() {Guess::new(200);}
}
测试结果:
$ cargo testCompiling guessing_game v0.1.0 (file:///projects/guessing_game)Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66sRunning unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d)running 1 test
test tests::greater_than_100 - should panic ... FAILEDfailures:---- tests::greater_than_100 stdout ----
thread 'tests::greater_than_100' panicked at src/lib.rs:12:13:
Guess value must be greater than or equal to 1, got 200.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
note: panic did not contain expected stringpanic message: `"Guess value must be greater than or equal to 1, got 200."`,expected substring: `"less than or equal to 100"`failures:tests::greater_than_100test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00serror: test failed, to rerun pass `--lib`
失败消息表明此测试确实发生了恐慌,但是恐慌消息不包含less than or equal to 100预期字符串。在这种情况下我们确实收到的恐慌信息是 Guess value must be greater than or equal to 1, got 200.。根据这个就可以纠错。
相关文章:
【Rust自学】11.4. 用should_panic检查恐慌
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 11.4.1. 验证错误处理的情况 测试函数出了验证代码的返回值是否正确,还需要验证代码是否如预期的去处理了发生错误的情况。比…...
高斯函数Gaussian绘制matlab
高斯 约翰卡尔弗里德里希高斯,(德语:Johann Carl Friedrich Gau,英语:Gauss,拉丁语:Carolus Fridericus Gauss)1777年4月30日–1855年2月23日,德国著名数学家、物理学家…...
获取客户端真实IP地址
当处理来自客户端的请求时,尤其是在存在代理服务器的情况下,可能需要考虑多种HTTP请求头,以尽可能准确地获取用户的真实IP地址。以下是考虑了X-Forwarded-For、Proxy-Client-IP、WL-Proxy-Client-IP、HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR的…...
Kotlin学习(一)
1. Kotlin 作用域函数 如果同学们已经在项目中用过 Kotlin 语言,那么一定见过 let 函数!因为每当 Kotlin 检测到某个对象可能为空时,会自动帮我们修改为用 let 函数实现:user.name?.let{ textView.text it }。这里的 let 函数就…...
鸿蒙UI开发——日历选择器
1、概 述 在项目开发中,我们时常会用到日历选择器,效果如下: ArkUI已经为我们提供了组件,我们可以直接使用,下面针对日历组件做简单介绍。 2、CalendarPickerDialog 接口定义如下: // 定义日历选择器弹…...
2025-1-9 QT 使用 QXlsx库 读取 .xlsx 文件 —— 导入 QXlsx库以及读取 .xlsx 的源码 实践出真知,你我共勉
文章目录 1. 导入QXlsx库2. 使用 QXlsx库 读取 .xlsx 文件小结 网上有很多教程,但太费劲了,这里有个非常简便的好方法,分享给大家。 1. 导入QXlsx库 转载链接 :https://github.com/QtExcel/QXlsx/blob/master/HowToSetProject.md…...
React中createRoot函数原理解读——Element对象与Fiber对象、FiberRootNode与HostRootNode
【2024最新版】React18 核心源码分析教程(全61集) Element对象与Fiber对象 在 React 中,Element 对象 和 Fiber 对象 是核心概念,用于实现 React 的高效渲染和更新机制。以下是它们的详细解读: 1. Element 对象 定…...
利用Python实现Union-Find算法
Union-Find(又称 并查集)是一种高效解决 动态连通性问题 的算法。它主要提供两种操作: Union(x, y):将元素 x 和 y 连接。Find(x):找到元素 x 所属的集合的标识符(通常是集合的根节点)。 常用…...
【LeetCode: 912. 排序数组 + 归并排序】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
AI时代来了,我们不再需要IDE了
大家好,我是编程乐趣。 最近在思考一个问题,那就是AI这么强大。 未来有没有可能,我们就不需要不需要开发工具了,只需一个浏览器就可以开发软件了。 一、AI带来的变化 1、代码生成与补全 AI工具如GitHub Copilot等能够根据代码…...
PL/SQL语言的网络编程
PL/SQL语言的网络编程 引言 在信息化迅速发展的今天,网络编程作为现代软件开发的重要组成部分,受到了广泛关注。而在数据库管理系统中,Oracle 提供了 PL/SQL(Procedural Language/Structured Query Language)&#x…...
vue video重复视频 设置 srcObject 视频流不占用资源 减少资源浪费
// 直接设置srcObject减少获取视频流:通过 captureStream() 方法从下方视频元素获取视频流。 // 设置 srcObject:将获取到的视频流设置为上方视频的 srcObject 减少资源浪费 // 获取到需要复制到的dom元素 const firstVideoElement proxy.$refs.firs…...
JavaFx 21 项目Markdown 预览、编辑、新建、文件树、删除、重命名
项目文件结构 项目的源代码和资源文件存放在以下路径: 源代码: src/main/java/com/kong/markdown/ 包含多个 Java 文件,主要实现了应用的功能: App.java:主类,可能包含应用的启动逻辑。FileService.java:可能与文件操作相关的服务类。MainController.java:控制器类,可…...
git项目提交步骤(简洁版)
1.创建仓库 2.填写 信息 3.点击这个按钮 4.找到要上传的文件,在目录内右键点击 5.依次执行命令 在命令窗口中输入:git init 复制仓库地址: 在命令窗口中输入:git remote add origin 仓库地址 在命令窗口中输入:…...
风水算命系统架构与功能分析
系统架构 服务端:Java(最低JDK1.8,支持JDK11以及JDK17)数据库:MySQL数据库(标配5.7版本,支持MySQL8)ORM框架:Mybatis(集成通用tk-mapper,支持myb…...
Clojure语言的学习路线
Clojure语言的学习路线 Clojure是一种现代的Lisp方言,运行于Java虚拟机(JVM)上。它具备强大的函数式编程特性,支持并发和多线程编程,适合处理复杂的数据和计算任务。由于其简洁和灵活的语法,Clojure在数据…...
网络安全核心目标CIA
网络安全的核心目标是为关键资产提供机密性(Confidentiality)、可用性(Availablity)、完整性(Integrity)。作为安全基础架构中的主要的安全目标和宗旨,机密性、可用性、完整性频频出现,被简称为CIA,也被成为你AIC,只是顺序不同而已…...
Wi-Fi Direct (P2P)原理及功能介绍
目录 Wi-Fi Direct (P2P)介绍Wi-Fi Direct P2P 概述P2P-GO(P2P Group Owner)工作流程 wifi-Direct使用windows11 wifi-directOpenwrtwifi的concurrent mode Linux环境下的配置工具必联wifi芯片P2P支持REF Wi-Fi Direct ÿ…...
Perl语言的数据结构
Perl语言的数据结构 Perl是一种功能强大的、灵活的脚本语言,广泛用于文本处理、系统管理、网络编程以及许多其他领域。其灵活性不仅体现在语法上,还体现在其丰富的数据结构上。本文将深入探讨Perl的主要数据结构,包括标量、数组、哈希以及引…...
【MFC】设置CTreeCtrl单个节点的文字颜色
问题 功能调整需要依据不同状态设置树控件中单个节点的文字颜色。 分析 1、CTreeCtrl本身有设置文字颜色的接口SetTextColor,但是这个接口是设置树控件整体的文字颜色。 2、在自定义接口可以对树控件单个节点进行更新文字颜色和背景颜色,接收自定义绘制…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
