当前位置: 首页 > news >正文

【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 < 1value > 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检查恐慌

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 11.4.1. 验证错误处理的情况 测试函数出了验证代码的返回值是否正确&#xff0c;还需要验证代码是否如预期的去处理了发生错误的情况。比…...

高斯函数Gaussian绘制matlab

高斯 约翰卡尔弗里德里希高斯&#xff0c;&#xff08;德语&#xff1a;Johann Carl Friedrich Gau&#xff0c;英语&#xff1a;Gauss&#xff0c;拉丁语&#xff1a;Carolus Fridericus Gauss&#xff09;1777年4月30日–1855年2月23日&#xff0c;德国著名数学家、物理学家…...

获取客户端真实IP地址

当处理来自客户端的请求时&#xff0c;尤其是在存在代理服务器的情况下&#xff0c;可能需要考虑多种HTTP请求头&#xff0c;以尽可能准确地获取用户的真实IP地址。以下是考虑了X-Forwarded-For、Proxy-Client-IP、WL-Proxy-Client-IP、HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR的…...

Kotlin学习(一)

1. Kotlin 作用域函数 如果同学们已经在项目中用过 Kotlin 语言&#xff0c;那么一定见过 let 函数&#xff01;因为每当 Kotlin 检测到某个对象可能为空时&#xff0c;会自动帮我们修改为用 let 函数实现&#xff1a;user.name?.let{ textView.text it }。这里的 let 函数就…...

鸿蒙UI开发——日历选择器

1、概 述 在项目开发中&#xff0c;我们时常会用到日历选择器&#xff0c;效果如下&#xff1a; ArkUI已经为我们提供了组件&#xff0c;我们可以直接使用&#xff0c;下面针对日历组件做简单介绍。 2、CalendarPickerDialog 接口定义如下&#xff1a; // 定义日历选择器弹…...

2025-1-9 QT 使用 QXlsx库 读取 .xlsx 文件 —— 导入 QXlsx库以及读取 .xlsx 的源码 实践出真知,你我共勉

文章目录 1. 导入QXlsx库2. 使用 QXlsx库 读取 .xlsx 文件小结 网上有很多教程&#xff0c;但太费劲了&#xff0c;这里有个非常简便的好方法&#xff0c;分享给大家。 1. 导入QXlsx库 转载链接 &#xff1a;https://github.com/QtExcel/QXlsx/blob/master/HowToSetProject.md…...

React中createRoot函数原理解读——Element对象与Fiber对象、FiberRootNode与HostRootNode

【2024最新版】React18 核心源码分析教程&#xff08;全61集&#xff09; Element对象与Fiber对象 在 React 中&#xff0c;Element 对象 和 Fiber 对象 是核心概念&#xff0c;用于实现 React 的高效渲染和更新机制。以下是它们的详细解读&#xff1a; 1. Element 对象 定…...

利用Python实现Union-Find算法

Union-Find&#xff08;又称 并查集&#xff09;是一种高效解决 动态连通性问题 的算法。它主要提供两种操作&#xff1a; Union(x, y)&#xff1a;将元素 x 和 y 连接。Find(x)&#xff1a;找到元素 x 所属的集合的标识符&#xff08;通常是集合的根节点&#xff09;。 常用…...

【LeetCode: 912. 排序数组 + 归并排序】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

AI时代来了,我们不再需要IDE了

大家好&#xff0c;我是编程乐趣。 最近在思考一个问题&#xff0c;那就是AI这么强大。 未来有没有可能&#xff0c;我们就不需要不需要开发工具了&#xff0c;只需一个浏览器就可以开发软件了。 一、AI带来的变化 1、代码生成与补全 AI工具如GitHub Copilot等能够根据代码…...

PL/SQL语言的网络编程

PL/SQL语言的网络编程 引言 在信息化迅速发展的今天&#xff0c;网络编程作为现代软件开发的重要组成部分&#xff0c;受到了广泛关注。而在数据库管理系统中&#xff0c;Oracle 提供了 PL/SQL&#xff08;Procedural Language/Structured Query Language&#xff09;&#x…...

vue video重复视频 设置 srcObject 视频流不占用资源 减少资源浪费

// 直接设置srcObject减少获取视频流&#xff1a;通过 captureStream() 方法从下方视频元素获取视频流。 // 设置 srcObject&#xff1a;将获取到的视频流设置为上方视频的 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.找到要上传的文件&#xff0c;在目录内右键点击 5.依次执行命令 在命令窗口中输入&#xff1a;git init 复制仓库地址&#xff1a; 在命令窗口中输入&#xff1a;git remote add origin 仓库地址 在命令窗口中输入&#xff1a;…...

风水算命系统架构与功能分析

系统架构 服务端&#xff1a;Java&#xff08;最低JDK1.8&#xff0c;支持JDK11以及JDK17&#xff09;数据库&#xff1a;MySQL数据库&#xff08;标配5.7版本&#xff0c;支持MySQL8&#xff09;ORM框架&#xff1a;Mybatis&#xff08;集成通用tk-mapper&#xff0c;支持myb…...

Clojure语言的学习路线

Clojure语言的学习路线 Clojure是一种现代的Lisp方言&#xff0c;运行于Java虚拟机&#xff08;JVM&#xff09;上。它具备强大的函数式编程特性&#xff0c;支持并发和多线程编程&#xff0c;适合处理复杂的数据和计算任务。由于其简洁和灵活的语法&#xff0c;Clojure在数据…...

网络安全核心目标CIA

网络安全的核心目标是为关键资产提供机密性(Confidentiality)、可用性(Availablity)、完整性(Integrity)。作为安全基础架构中的主要的安全目标和宗旨&#xff0c;机密性、可用性、完整性频频出现&#xff0c;被简称为CIA&#xff0c;也被成为你AIC&#xff0c;只是顺序不同而已…...

Wi-Fi Direct (P2P)原理及功能介绍

目录 Wi-Fi Direct &#xff08;P2P&#xff09;介绍Wi-Fi Direct P2P 概述P2P-GO&#xff08;P2P Group Owner&#xff09;工作流程 wifi-Direct使用windows11 wifi-directOpenwrtwifi的concurrent mode Linux环境下的配置工具必联wifi芯片P2P支持REF Wi-Fi Direct &#xff…...

Perl语言的数据结构

Perl语言的数据结构 Perl是一种功能强大的、灵活的脚本语言&#xff0c;广泛用于文本处理、系统管理、网络编程以及许多其他领域。其灵活性不仅体现在语法上&#xff0c;还体现在其丰富的数据结构上。本文将深入探讨Perl的主要数据结构&#xff0c;包括标量、数组、哈希以及引…...

【MFC】设置CTreeCtrl单个节点的文字颜色

问题 功能调整需要依据不同状态设置树控件中单个节点的文字颜色。 分析 1、CTreeCtrl本身有设置文字颜色的接口SetTextColor&#xff0c;但是这个接口是设置树控件整体的文字颜色。 2、在自定义接口可以对树控件单个节点进行更新文字颜色和背景颜色&#xff0c;接收自定义绘制…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...