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

Rust之错误处理

在Rust中,将错误分为两种,可恢复错误和不可恢复错误。所谓可恢复错误就是指类似于文件未找到这类错误,一般需要将它们报告给用户并再次尝试进行操作,而不可恢复错误往往就是Bug,需要停止程序的运行。

1、不可恢复错误与panic!:

当代码中出现没有预料到的错误时,Rust提供了一个特殊的宏panoc!,程序会在panic!宏执行时打印一段错误提示信息,展开并清理当前的调用栈,然后退出程序的执行。
当panic发生时,程序会默认开始栈展开。这意味着Rust会沿着调用栈的反向顺序遍历所有调用函数,并依次清理这些函数中的数据。但是为了支持这种遍历和清理操作,我们需要在二进制中存储许多额外信息。

2、可恢复错误与Result:

在程序的调试中,有些错误没有严重到需要停止整个程序的运行,例如尝试打开一个文件,而文件不存在的情况。这种情况可以使用Result类型来处理。在Result枚举中,定义了两个变体——OK和Err。示例:

enum Result<T,E>{OK(T),Err(E),
}

这里的T和E都是泛型,T代表了OK变体中包含的值的类型,该变体中的值会在执行成功时返回;E代表了Err变体中包含的错误类型,该变体会在执行失败时返回。

(1)、匹配不同的错误:

由于在编程时,会遇到不同的错误,那么就可以根据错误的种类来执行不同的操作。示例:

use std::fs::File;
use std::io::ErrorKind;
fn main() {let f = File::open("hello.txt");let f = match f {Ok(file) => file,Err(error) => match error.kind() {ErrorKind::NotFound => match File::create("hello.txt") {Ok(fc) => fc,Err(e) => panic!("Tried to create file but there was a problem:{:?}", e),},other_error => panic!("There was a problem opening the file: {:?}",other_error),},};
}

File::open返回的Err变体中的错误值类型,是定义在某个标准库中的结构体类型:io::Error。这个结构体拥有一个被称作kind的方法,可以通过调用它来获得 io::ErrorKind 值。这个io::ErrorKind枚举是由标准库提供的,它的变体被用于描述io操作所可能导致的不同错误。这里使用的变体是ErrorKind::NotFound,它用于说明我们尝试打开的文件不存在。所以,我们不但对变量f使用了match表达式,还在内部对error.kind()使用了match表达式。

(2)、失败时触发panic的快捷方式:unwrap和expect:

虽然使用match运行得很不错,但使用它所编写出来的代码可能会显得有些冗长,且无法较好地表明其意图。类型Result<T, E>本身也定义了许多辅助方法来应对各式各样的任务。当Result的返回值是Ok变体时,unwrap就会返回Ok内部的值。而当Result的返回值是Err变体时,unwrap则会替我们调用panic! 宏。示例:

use std::fs::File;
fn main() {let f = File::open("hello.txt").unwrap();
}

还有另外一个被称作expect的方法,它允许我们在unwrap的基础上指定panic! 所附带的错误提示信息。使用expect并附带上一段清晰的错误提示信息可以阐明你的意图,并使你更容易追踪到panic的起源。示例:

use std::fs::File;
fn main() {let f = File::open("hello.txt").expect("Failed to open hello.txt");
}

使用expect所实现的功能与unwrap完全一样:要么返回指定文件句柄,要么触发panic! 宏调用。唯一的区别在于,expect触发panic! 时会将传入的参数字符串作为错误提示信息输出,而unwrap触发的panic! 则只会携带一段简短的默认信息。

(3)、传播错误:

编写的函数中包含了一些可能会执行失败的调用时,除了可以在函数中处理这个错误,还可以将这个错误返回给调用者,让他们决定应该如何做进一步处理。这个过程也被称作传播错误,在调用代码时它给了用户更多的控制能力。与编写代码时的上下文环境相比,调用者可能会拥有更多的信息和逻辑来决定应该如何处理错误。
传播错误的模式在Rust编程中非常常见,所以Rust专门提供了一个问号运算符(?)来简化它的语法。示例:

use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {let mut f = File::open("hello.txt")?;let mut s = String::new();f.read_to_string(&mut s)?;Ok(s)
}

通过将放置于Result值之后,我们实现了与使用match表达式来处理Result时一样的功能。假如这个Result的值是Ok,那么包含在Ok中的值就会作为这个表达式的结果返回并继续执行程序。假如值是Err,那么这个值就会作为整个程序的结果返回,如同使用了return一样将错误传播给调用者。
match表达式与运算符的一个区别:被运算符所接收的错误值会隐式地被from函数处理,这个函数定义于标准库的From trait中,用于在错误类型之间进行转换。当运算符调用from函数时,它就开始尝试将传入的错误类型转换为当前函数的返回错误类型。当一个函数拥有不同的失败原因,却使用了统一的错误返回类型来同时进行表达时,这个功能会十分有用。只要每个错误类型都实现了转换为返回错误类型的from函数,?运算符就会自动处理所有的转换过程。
注:?运算符只能被用于返回Result的函数。

3、要不要使用panic!:

什么时候应该使用panic!,而什么时候又应该返回Result呢?代码一旦发生panic,就再也没有恢复的可能了。只要你认为自己可以代替调用者决定某种情形是不可恢复的,那么就可以使用panic!,而不用考虑错误是否存在可以恢复的机会。当你选择返回一个Result值时,你就将这种选择权交给了调用者。调用者可以根据自己的实际情况来决定是否要尝试进行恢复,或者干脆认为Err是不可恢复的,并使用panic! 来将可恢复错误转变为不可恢复错误。因此,我们会在定义一个可能失败的函数时优先考虑使用Result方案。

相关文章:

Rust之错误处理

在Rust中&#xff0c;将错误分为两种&#xff0c;可恢复错误和不可恢复错误。所谓可恢复错误就是指类似于文件未找到这类错误&#xff0c;一般需要将它们报告给用户并再次尝试进行操作&#xff0c;而不可恢复错误往往就是Bug&#xff0c;需要停止程序的运行。 1、不可恢复错误…...

docker compose快速编排

Docker-compose概述 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容集群的快速编排 Docker-Compose将所管理的容器分为三层&#xff0c;分别是工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#xff09;以及容器&#x…...

java.io.File类的使用

文章目录 概述构造器常用方法1、获取文件和目录基本信息2、列出目录的下一级3.File类的重命名功能4、判断功能的方法5、创建、删除功能 练习 概述 File类及本章下的各种流&#xff0c;都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录&#…...

TypeScript技能总结(三)

typescript是js的超集&#xff0c;目前很多前端框架都开始使用它来作为项目的维护管理的工具&#xff0c;还在不断地更新&#xff0c;添加新功能中&#xff0c;我们学习它&#xff0c;才能更好的在的项目中运用它&#xff0c;发挥它的最大功效 //泛型 > 参数和返回值类型相…...

python绿色版运行程序,python 绿色版免安装

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python绿色版运行程序&#xff0c;python 绿色版免安装&#xff0c;今天让我们一起来看看吧&#xff01; 软件简介 Python3.7.0 是一种被广大从业者广泛使用的通用型设计语言。该软件提供了丰富全面的模块&#xff0c;并…...

Python 向Excel写数据

1.项目终端导入 xlwt 库 pip install xlwt2.导入依赖包 import xlwt3.创建Excel表格类型文件 调用xlwt模块中的Workbook方法来创建一个excel表格类型文件&#xff0c;其中的第一个参数是设置数据的编码格式&#xff0c;这里是’utf-8’的形式&#xff0c;style_compression设…...

MySQL(1)

MySQL创建数据库和创建数据表 创建数据库 1. 连接 MySQL mysql -u root -p 2. 查看当前的数据库 show databases; 3. 创建数据库 create database 数据库名; 创建数据库 4. 创建数据库时设置字符编码 create database 数据库名 character set utf8; 5. 查看和显示…...

Android10 Recovery系列(二)增加OTG升级功能

一 、背景 起因是遇到了客户有这个需求,本着了解的原则,去看了一下之前Android版本的代码,想看看之前有没有现成的实现,移植过来。结果很不幸,没有找到。于是自己开始了功能实现的过程。下面分享一下该功能的实现 二 、准备工作 首先简单了解一下Recovery 模块的系统升…...

el-popover使用自定义图标

使用el-popover实现鼠标点击或浮动到自定义图标上弹出表格弹窗&#xff0c;官方文档上使用的是按钮el-button&#xff0c;如果想换成图标或其他的组件的话直接把el-button替换掉即可。注意替换之后的组件一定要加slot“reference”&#xff0c;不然组件是显示不出来的。 代码如…...

KCOM4串口转键鼠控制线测试说明

1.KOCM4介绍 KCOM4是一款最新开发的串口转键盘鼠标控制线&#xff0c;采用32位内核&#xff0c;最大60Mhz的工作频率&#xff0c;完美适用于游戏挂机等应用场景&#xff08;如果是用在工作电脑控制或展厅电脑控制推荐CH9329双头线&#xff09;。KCOM4支持普通键盘、相对鼠标、…...

2023华数杯数学建模C题完整5问代码思路分析

目前已经写出2023华数杯C题母亲身心健康对婴儿成长的影响全部5问的完整代码和42页论文&#xff08;正文30页&#xff0c;论文部分摘要如下&#xff1a; 本文共解决了五个问题&#xff0c;涉及婴儿行为特征、睡眠质量与母亲的身体指标和心理指标的关系&#xff0c;以及如何优化…...

02_kafka_基本概念_基础架构

文章目录 常见的消息队列工作模式基本概念kafka 特性Kafka 基本架构topic 分区的 目的/ 好处 日志存储形式消费者&#xff0c;消费方式 逻辑消费组 高性能写入&#xff1a; 顺序写 mmap读取&#xff1a;零拷贝DMA 使用场景 常见的消息队列工作模式 至多一次&#xff1a;消息被…...

HTTP 常用状态码 301 302 304 403

HTTP 常用状态码 301 302 304 403 301 永久重定向&#xff0c;浏览器会把重定向后的地址缓存起来&#xff0c;将来用户再次访问原始地址时&#xff0c;直接引导用户访问新地址 302 临时重定向&#xff0c;浏览器会引导用户进入新地址&#xff0c;但不会缓存原始地址&#xff0c…...

分布式 - 服务器Nginx:一小时入门系列之静态网页配置

文章目录 1. 静态文件配置2. nginx listen 命令解析3. nginx server_name 命令解析4. nginx server 端口重复5. nginx location 命令 1. 静态文件配置 在 /home 文件下配置一个静态的AdminLTE后台管理系统&#xff1a; [rootnginx-dev conf.d]# cd /home [rootnginx-dev home…...

kubernetes网络之网络策略-----Network Policies - Example

创建一个Deployment并配置Service 创建一个 nginx Deployment 用于演示 Kubernetes 的 NetworkPolicy&#xff1a; kubectl create deployment nginx --imagenginx 输出结果 deployment.apps/nginx created通过Service暴露该Deployment kubectl expose deployment nginx --po…...

【GDI/GDI+】如何抓取屏幕保存到bitmap文件?

问题 如何抓取屏幕保存到bitmap文件&#xff1f; 方法 GDI 方法 1、抓取。 HBITMAP CRectChartUI::GetBitmap(HDC hDC) {HDC hMemDC;int x, y;int nWidth, nHeight;HBITMAP hBitmap, hOldBitmap;hMemDC CreateCompatibleDC(hDC);nWidth GetDeviceCaps(hDC, HORZRES);nHei…...

HDFS介绍

目录 ​编辑 一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块&#xff08;Block&#xff09; 1.3.2 复制…...

每日一题——两数之和

题目 给出一个整型数组 numbers 和一个目标值 target&#xff0c;请在数组中找出两个加起来等于目标值的数的下标&#xff0c;返回的下标按升序排列。 &#xff08;注&#xff1a;返回的数组下标从1开始算起&#xff0c;保证target一定可以由数组里面2个数字相加得到&#xff0…...

Maven: ‘mvn‘ is not recognized as an internal or external command

下载并配置好Maven之后&#xff0c;CMD测试安装是否成功&#xff1a;mvn -v 提示&#xff1a; mvn is not recognized as an internal or external command, operable program or batch file. 检查环境变量&#xff1a; MAVEN_HOME: %MAVEN_HOME%\bin: 看上去没问题&#x…...

CubeSLAM: Monocular 3D Object SLAM——论文简述

一、简介 提出一种在动态和静态环境中同时进行3D目标检测和定位建图的方法&#xff0c;并且能够互相提升准确度。具体地&#xff0c;对于3D目标&#xff0c;其位置、方向和尺寸通过slam进行了优化&#xff1b;而3D目标作为slam中的路标&#xff0c;可以提供额外的语义和几何约…...

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

linux scp 拷贝文件到目标linux系统

scp -P 8866 -r jsonrpc/ root192.168.6.66:/folder_path...

Oracle-expdp报错ORA-39077、06502(Bug-16928674)

问题: 用户在使用expdp进程导出时&#xff0c;出现队列报错ORA-39077、ORA-06502 ORA-31626: job does not exist ORA-31638: cannot attach to job SYS_EXPORT_SCHEMA_01 for user SYS ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95 ORA-06512: at "SYS.KUPV$…...

Kafka入门,保姆级教学

文章目录 Kafka概念消息中间件对比消息中间件对比-选择建议Kafka常用名词介绍Kafka入门1. Kafka安装配置2.Kafka生产者与消费者关系3.Kafka依赖4.生产者发消息5.消费者接受消息6.Kafka高可用性设计6.1集群Kafka备份机制(Reolication) 7.kafka生产者详解7.1 发送类型7.2参数详解…...

RabbitMQ 过期时间(TTL)

TTL,Time to Live的简称&#xff0c;即过期时间&#xff0c;RabbitMQ可以对消息和队列设置TTL。 RabbitMQ支持设置队列的过期时间和消息的过期时间。如果设置队列的过期时间则队列中所有的消息都有相同的过期时间。如果设置消息的过期时间则每条消息的过期时间则可以不同。如两…...

C 语言练习题、持续更新

文章目录 C语言练习题读懂每个练习题才是学好一门代码的重要经历目录&#xff08;先不要看答案&#xff0c;首先自己做才能更好的领悟&#xff0c;做不来没关系&#xff09;题目一&#xff1a;有 1、2、3、4 四个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&…...

Android Q以上后台启动Activity初步尝试

在Android Q以后 google不允许在后台service 广播等等启动Activity 具体请看google文档从后台启动 Activity 的限制 | Android 开发者 | Android Developers 文档里有详细的说明,在哪种情况下可以后台启动Activity。 大体分为以下几种情况: 1、应用具有可见窗口,例如前…...

【torchlars】windows下载github中的torchlars包遇到的问题及解决方案

环境 python3.7 windows10 cuda11.1 pytorch1.8.1 虚拟环境miniconda 目的 windows下载github中的torchlars包 遇到的问题 问题一&#xff1a;直接下载好文件夹输入指令&#xff1a;python setup.py install 出现错误&#xff1a;RuntimeError: Error compiling objects f…...

SolidUI社区-通用Prompt技巧

背景 随着文本生成图像的语言模型兴起&#xff0c;SolidUI想帮人们快速构建可视化工具&#xff0c;可视化内容包括2D,3D,3D场景&#xff0c;从而快速构三维数据演示场景。SolidUI 是一个创新的项目&#xff0c;旨在将自然语言处理&#xff08;NLP&#xff09;与计算机图形学相…...

C++中类的封装写出一个文件加密的小项目

文件的加密较为简单&#xff0c;当然也可以修改它的加密方式等&#xff0c;供大家参考 #include<string> #include<fstream> class ReaderFile { public:string Read(const string& filename){cout << "读取文件&#xff0c;获取明文"<<…...