019、错误处理:不可恢复错误与panic!
鉴于上一篇文章过长,不方便大家阅读和理解,因此关于Rust中的错误处理, 我将分以下3篇来讲。
另外,随着我们学习的不断深入,难度也会越来越大,但不用担心。接下来只需要让自己的脚步慢一些,认真搞懂每一篇文章的知识点,把示例代码也在自己电脑上敲一敲,相信大家终会有所收获,因为时间是最好的见证人。角角与诸君共勉!
1. 分享几个关于VS Code的使用小技巧
在正式讲解之前,角角想分享一下关于 VS Code 的几个使用小技巧,也是我最近了解到并开始使用的,如果你已经知道了可以直接略过哈~
看上面这张截图,界面和字体是不是你喜欢的风格呢?反正角角直接爱了~
首先是左侧文件树每个文件夹的图标,颜色都比较鲜艳也容易区分,图标设计的也非常好看,这是安装了一个叫:Material Icon Theme 的插件,在拓展商店中输入 icon,第一个结果就是啦!
第二个分享的插件是:Houston,这个插件可以让你的代码变得五彩斑斓,和上面的文件夹图标是不是很搭呢?它最有意思的功能是在工作区出现一个方块脸的悬浮窗,当你写的代码没有错误时,它会显示一个笑脸,相反,则是一个哭脸,是不是很有意思?
如果你启用了这个扩展但是并没有出现方块脸,那你就需要在 资源管理器 中单击 HOUSTON 这个文件夹,展开它之后方块脸就在左下方出现啦!
要是你不喜欢这种花里胡哨,只追求实用性,那么我推荐你使用 One Dark Pro 这个主题,颜色看起来非常的舒适,很多大佬也都用这个。对了,这个和上面的方块表情是可以同时使用的哦~
第三个是快捷键,我每次写一行代码的时候,中间输入完了,然后又要用鼠标点到末尾加个分号,真的很烦哎!
然后我就网上查了一下,果然有解决的办法,就是键盘上的 End 键!然后 End 键上面的就是 Home 键。当你的光标在一行代码中间位置时,按一下 End 键就可以快速跳转到该行代码的末尾,然后再随手敲一个分号和回车,是不是棒极了?
Home 键与之相反,按一下则会跳转到该行代码的开始位置,用的不多。
如果是笔记本的话,就按组合键:Fn + End,Fn + Home 。
最后一个组合快捷键是:Shift + Alt + 下方向键,这个的作用就是将光标所在的那一行代码再复制到下一行,这个用的场景还是比较多的,大家可以记一下。
后面角角再发现一些小技巧会不定时分享在文章中的,真心希望能帮助到大家,如果你们也有一些好用的小技巧也不妨分享在评论区哈~
2. 不可恢复错误与panic!
Rust提供了一个特殊的 panic! 宏。程序会在 panic! 宏执行时打印出一段错误提示信息,展开并清理当前的调用栈,然后退出程序。这种情况大部分都发生在某个错误被检测到,但程序员却不知该如何处理的时候。
当 panic!宏执行会有以下3个动作:
💫 你的程序会打印一个错误信息
💫 展开(unwind)、清理调用栈(Stack)
💫 退出程序
在默认情况下,当 panic 发生,有以下两种情况:
💫 程序展开调用栈(工作量大):Rust沿着调用栈往回走,清理每个遇到的函数中的数据
💫 立即中止调用栈:不进行清理,直接停止程序,内容让操作系统(OS)去处理
如果你想让二进制文件(exe文件)更小,可以把设置从“展开”改为“中止”。设置方法就是,在 Cargo.toml 文件中适当的 profile 部分设置,即添加:panic = 'abort' 。
下面简单敲一行代码,试试这个 panic!宏:
fn main() {panic!("我是练习时长两年半的角角!");
}
输出结果如下:
thread 'main' panicked at src\main.rs:2:5:
我是练习时长两年半的角角!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\error.exe` (exit code: 101)
好多英文看不懂,翻译一下:
线程“main”在src\main处惊慌失措。rs:2:5:
我是练习时长两年半的角角!
注意:使用“RUST_BACKTRACE=1”环境变量运行以显示回溯
错误:进程未成功退出:`target\debug\error.exe`(退出代码:101)
结果第一行中的 src\main.rs:2:5 表示:恐慌发生在 src\main.rs 文件中的第二行第五个字符处。而指向的这个地方,正是我们调用 panic!宏的地方。
一般情况下,panic!宏是和其它一些代码结合使用的,并不会单单像我们这样就只敲一行代码。我们可以通过查看 panic! 调用函数的回溯信息来定位代码出现问题的地方。
这里引出一个新的概念,回溯信息。
3. 使用panic! 产生的回溯信息
先举个🌰,我先创建一个动态数组,然后里面放3个元素,但我会用索引访问其中的第10个元素。
fn main() {let v = vec![1, 2, 3];v[9];
}
像这种越界访问,编译器就没有提前检测出错误, 但会导致 panic。
在类似于C这样的语言中,程序在这种情况下依然会尝试返回你所请求的值,即便这可能会与你所期望的并不相符:你会得到动态数组中对应这个索引位置的内存,而这个内存可能存储了其他数据,甚至都不属于动态数组本身。
这种情形也被称为缓冲区溢出(buffer overread),并可能导致严重的安全性问题。攻击者可以通过操纵索引来访问存储在数组后面的、那些不被允许读取的数据。
我们运行一下上面的例子,看看报错内容:
thread 'main' panicked at src\main.rs:3:6:
index out of bounds: the len is 3 but the index is 9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\error.exe` (exit code: 101)
翻译一下:
线程“main”在src\main处惊慌失措。rs:3:6:
索引越界:len为3,但索引为9
注意:使用“RUST_BACKTRACE=1”环境变量运行以显示回溯
错误:进程未成功退出:`target\debug\error.exe`(退出代码:101)
第一行是告诉我们错误的位置,第二行是错误的原因,第三行提示我们可以通过设置环境变量 RUST_BACKTRACE 来得到回溯信息,进而确定触发错误的原因。回溯中包含了到达错误点的所有调用函数列表。
在Rust中使用回溯的方式与在其他语言中的使用方式类似:从头开始查看回溯列表,直至定位到自己所编写代码的文件,而这也正是产生问题的地方。
从定位到文件的那一行往上是我们代码所调用的代码,往下则是调用了我们代码的代码。这些调用中可能会包含Rust核心库、标准库,以及你所使用的第三方库。
让我们来将环境变量 RUST_BACKTRACE 设置为一个 非0值,从而获得回溯信息。在Windows操作系统下的 PowerShell 窗口中分别输入:
$env:RUST_BACKTRACE="full"
cargo run
得到的回溯信息如下:
thread 'main' panicked at src\main.rs:3:6:
index out of bounds: the len is 3 but the index is 9
stack backtrace:0: 0x7ff7207872ea - std::sys_common::backtrace::_print::impl$0::fmtat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\sys_common\backtrace.rs:441: 0x7ff72079508b - core::fmt::rt::Argument::fmtat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\core\src\fmt\rt.rs:1382: 0x7ff72079508b - core::fmt::writeat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\core\src\fmt\mod.rs:11143: 0x7ff7207856b1 - std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\io\mod.rs:17634: 0x7ff72078706a - std::sys_common::backtrace::_printat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\sys_common\backtrace.rs:475: 0x7ff72078706a - std::sys_common::backtrace::printat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\sys_common\backtrace.rs:346: 0x7ff72078905a - std::panicking::default_hook::closure$1at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:2727: 0x7ff720788cc8 - std::panicking::default_hookat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:2928: 0x7ff720789708 - std::panicking::rust_panic_with_hookat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:7319: 0x7ff7207895ed - std::panicking::begin_panic_handler::closure$0at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:60910: 0x7ff720787cd9 - std::sys_common::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure_env$0,never$>at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\sys_common\backtrace.rs:17011: 0x7ff720789300 - std::panicking::begin_panic_handlerat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:59712: 0x7ff720799eb7 - core::panicking::panic_fmtat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\core\src\panicking.rs:7213: 0x7ff72079a044 - core::panicking::panic_bounds_checkat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\core\src\panicking.rs:18014: 0x7ff7207812bd - core::slice::index::impl$2::index<i32>at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\core\src\slice\index.rs:26115: 0x7ff720781076 - alloc::vec::impl$12::index<i32,usize,alloc::alloc::Global>at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\alloc\src\vec\mod.rs:272816: 0x7ff720781a96 - error::mainat C:\Users\45570\Desktop\rust_demo\error\src\main.rs:317: 0x7ff7207818bb - core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\core\src\ops\function.rs:25018: 0x7ff7207817be - std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\std\src\sys_common\backtrace.rs:15419: 0x7ff7207817be - std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\std\src\sys_common\backtrace.rs:15420: 0x7ff720781831 - std::rt::lang_start::closure$0<tuple$<> >at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\std\src\rt.rs:16621: 0x7ff720783ba8 - std::rt::lang_start_internal::closure$2at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\rt.rs:14822: 0x7ff720783ba8 - std::panicking::try::do_callat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:50423: 0x7ff720783ba8 - std::panicking::tryat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panicking.rs:46824: 0x7ff720783ba8 - std::panic::catch_unwindat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\panic.rs:14225: 0x7ff720783ba8 - std::rt::lang_start_internalat /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library\std\src\rt.rs:14826: 0x7ff72078180a - std::rt::lang_start<tuple$<> >at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1\library\std\src\rt.rs:16527: 0x7ff720781af9 - main28: 0x7ff720798940 - invoke_mainat D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:7829: 0x7ff720798940 - __scrt_common_main_sehat D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:28830: 0x7fff42d0257d - BaseThreadInitThunk31: 0x7fff44f4aa58 - RtlUserThreadStart
error: process didn't exit successfully: `target\debug\error.exe` (exit code: 101)
在回溯信息的第16行,它指出了程序的主要错误在 main.rs 文件的第3行。在这个 error::main 的上方就是我们调用的代码,而下方则是调用我们所写代码的代码。
若你想关闭回溯,可以使用如下命令:
$env:RUST_BACKTRACE=0
如果将来代码发生了 panic,你就需要自己去搞清楚代码中的哪些操作或哪些值导致了 panic,并且思考应该如何修改代码以避免出现问题。
下篇文章将介绍可恢复错误与Result,角角期待你的订阅与关注,咱们下篇见!
相关文章:

019、错误处理:不可恢复错误与panic!
鉴于上一篇文章过长,不方便大家阅读和理解,因此关于Rust中的错误处理, 我将分以下3篇来讲。 另外,随着我们学习的不断深入,难度也会越来越大,但不用担心。接下来只需要让自己的脚步慢一些,认真搞…...

jar包部署到linux虚拟机的docker中之后连不上mysql
前言: 跟着黑马学习docker的时候,将java项目部署到了docker中,运行访问报错,反馈连不上mysql。 错误描述: 方法解决: 概述:在虚拟中中,我进入项目容器的内部,尝试ping…...

如何筛选小红书护肤达人,笔记类型怎么选?
网络时代,借助KOL来放大产品的声量和产量,是品牌的常见策略,但是,不同的产品对应不同的KOL,价值是完全不一样。如何筛选达人,已经成为了品牌方的必修课!今天我们和大家分享下如何筛选小红书护肤达人&#x…...

红黑树(RBTree)
目录 一、红黑树简介 二、红黑树的来源 三、什么是红黑树 四、红黑树的性质 五、红黑树的节点定义 六、红黑树的操作 6.1、红黑树的查找 6.2、红黑树的插入 七、红黑树的验证 八、红黑树和AVL树的比较 一、红黑树简介 红黑树是一种自平衡的二叉查找树…...

训练YOLOS-S
文章目录 1 数据处理2 配置训练参数3 可能会遇到的报错 1 数据处理 修改类别数:在models/detector.py中定位到def build(args):,将num_classes进行修改,改为最大的类别id1。我有4个类别,类别id是从0~3,因此max_id3&am…...
集成SpringCloudAlibaba短信服务 短信验证码
1.1 SpringCloudAlibaba短信服务简介 短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。 产品优势:覆盖全面、高并发处理、消息堆积处理、开发管理简单、智能监控调度 产品功能:短信通知、短信验证码、…...

存储卷(数据卷)—主要是nfs方式挂载
1、定义 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的,一旦容器被删除,数据会丢失。k8s基于控制器创建的pod,delete相当于重启,容器的状态会恢复到原始状态。一旦回到原始状态,后天编辑的文件…...

城市酷选模式开发(门店免单排队返利系统)
城市酷选模式开发(门店免单排队返利系统)【阿巴】城市酷选商城开发免单排队返利小程序搭建、城市酷选模式开发、城市酷选系统商城开发、城市酷选APP系统开发、城市酷选 每经AI快讯,有投资者在投资者互动平台提问:“以塑代钢”已成…...

JNPF低代码引擎到底是什么?
最近听说一款可以免费部署本地进行试用的低代码引擎,源码上支持100%源码,提供的功能和技术支持比较完善。借助这篇篇幅我们了解下JNPF到底是什么? JNPF开发平台是一款PaaS服务为核心的零代码开发平台,平台提供了多租户账号管理、主…...
#基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
我们在使用jupyter 写代码后,经常遇到一些写完想把文件转成markdown格式的场景,这里就教你怎么处理相关的问题 使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件 pip install nbconvert pip install pandoc jupyter nbconvert --to markdown 文…...

工信部颁发的人工智能证书《自然语言与语音处理设计开发工程师》证书到手啦!
工信部颁发的人工智能证书《自然语言与语音处理设计开发工程师》证书拿到手啦! 近期正在报考的工信部颁发的人工智能证书还有: 《计算机视觉处理设计开发工程师》中级 2024年1月24日至28日-北京 《自然语言与语音处理设计开发工程师》中级 第二期 20…...

canvasdrawer 微信原生小程序生成海报图片
在小程序中生成海报是一种非常有效的推广方式 用户可以使用小程序的过程中生成小程序海报并分享给他人 通过海报的形式,用户可以直观地了解产品或服务的特点和优势 常见绘制海报方式 目前,小程序海报有两种常见的实现方式: canvas 绘制…...

linux基础学习(3):挂载
挂载可以理解为给磁盘空间一个可访问的入口,那个入口称为挂载点,相当于windows中的盘符。 1.挂载命令mount 1.1直接输入mount 查看系统已挂载的设备 1.2挂载与卸载命令 mount -t 文件系统名 设备文件名 挂载点 | umount 挂载点 或 umount 设…...

[每周一更]-(第82期):认识自然处理语言(NLP)
GPT的大火,带起了行业内大模型的爆发;国内外都开始拥有或者研发自己的大模型,下边我们从NLP来进一步深入了解大模型、AI。 一、什么是NLP? 自然语言处理(英语:Natural Language Processing,缩…...

Win11如何设置时间显示秒
1、打开注册表 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced 2、进入以上路径 Advanced新建dword32位,新建一个文件,设置一个名称 3、修改之前创建的文件 4、重启电脑...

世界人口数据分析与探索
文章目录 世界人口数据集介绍数据集 1:世界国家统计数据:数据集 2:世界人口详细信息(2023 年):数据集 3:按年份划分的世界人口(1950-2023): 数据分析导入必要…...

自动驾驶的未来:BEV与Occupancy网络全景解析与实战揭秘!
自动驾驶领域中,什么是BEV?什么是Occupancy? 作者:小柠檬 | 来源:公众号「3DCV」 BEV是Bird’s Eye View 的缩写,意为鸟瞰视图。在自动驾驶领域,BEV 是指从车辆上方俯瞰的场景视图。BEV 图像可以…...

大众点评评论采集软件使用教程
导出字段: 店铺ID 评论ID 发布时间 人均消费 评分 详情链接 点赞数 浏览数 评论数 最后更新时间 发布平台 推荐 评论详情 原始评论 图片数 图片链接 用户等级 用户名称 用户头像 VIP 私...

2024年前端面试中JavaScript的30个高频面试题之中级知识
基础知识 高级知识 13. 什么是闭包?闭包的用例有哪些? 闭包是一个功能,它允许函数捕获定义该函数的环境(或保留对作用域中变量的访问)即使在该作用域已经关闭后。 我们可以说闭包是函数和词法环境的组合,其中定义了该函数。 换句话说,闭包为函数提供了访问自己的作用域、…...

postman 简单测试(一)
1.postman官网 Postman API Platform 2.研究了一下postman 一些简单的功能,自己做个记录,同时希望能节约点测试时间。 2.1新建一个 collections 长期测的话,最好注册一个账号,开放更多功能。 2.2新建一个请求 后端要先搭建起来…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...