30天拿下Rust之错误处理

概述

        在软件开发领域,对错误的妥善处理是保证程序稳定性和健壮性的重要环节。Rust作为一种系统级编程语言,以其对内存安全和所有权的独特设计而著称,其错误处理机制同样体现了Rust的严谨与实用。在Rust中,错误处理通常分为两大类:不可恢复的错误和可恢复的错误。这两种错误的处理方式在Rust的设计哲学中扮演着不同的角色,并且适用于不同的场景。

不可恢复的错误

        不可恢复的错误是指那些由于严重问题,导致程序无法继续执行的情况。这类错误通常是由于编程错误、资源耗尽、或者外部系统问题导致的。在Rust中,不可恢复的错误通过panic!宏来触发。

        当panic!被调用时,程序会立即停止当前的执行流程,并打印出一条错误消息,然后退出程序。因为panic!会导致程序崩溃,所以它通常只在开发过程中用于检测那些不应该发生的严重错误。

        在下面的示例代码中,如果除数b为0,会通过panic!宏来触发不可恢复的错误,并打印错误消息“Division by zero”。panic!被调用后,程序会立即终止,因此,后面的println!不会执行。

fn divide(a: i32, b: i32) -> i32 {if b == 0 {panic!("Division by zero");}a / b
}fn main() {let value = divide(66, 0);println!("{}", value);
}

        注意:在生产代码中,应当尽量避免使用panic!,因为它会导致程序不稳定和不可靠。相反,应该使用下面介绍的可恢复的错误机制来优雅地处理可能出现的错误,并确保程序在遇到问题时,能够以一种可预测和可控的方式做出响应。

可恢复的错误

        可恢复的错误是指那些可以通过某种方式修正或处理的错误,通常不会导致程序完全崩溃。在Rust中,这类错误通常通过Result枚举类型来表示。Result有两个可能的变体:Ok用于表示操作成功的结果,而Err用于表示错误。

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

        使用Result枚举类型,函数可以显式地表示它们可能失败,并返回一个错误值。调用这些函数的代码,可以选择如何处理这些错误,比如:重试、提供默认值、或者将错误传递给上层调用者。这种错误处理机制允许程序在发生错误时保持运行,并可能从错误中恢复。

        在下面的示例代码中,我们调用File::open方法尝试打开名为“CSDN.txt”的文件。这个方法返回一个Result类型,其中Ok变体包含文件句柄(如果文件打开成功),而Err变体包含错误信息(如果文件打开失败)。

use std::fs::File;fn main() {let file_handle = File::open("CSDN.txt");match file_handle {Ok(file) => {println!("open successfully");},Err(err) => {println!("failed: {}", err);}}
}

        如果想将一个可恢复的错误按照不可恢复的错误处理,Result类提供了两个方法:unwrap()和expect()。这两个方法是用于处理Result或Option类型的便捷方法,用于从这些类型中提取出内部值,但当值不存在(对于Option)或是一个错误状态(对于Result)时,都会导致程序panic。如果Option是None或者Result是Err(E),则unwrap()会触发panic,并打印出默认的panic!消息。expect()方法与unwrap()方法类似,但它允许我们自定义在panic时输出的错误消息。

fn main() {let opt_value: Option<i32> = Some(66);let value = opt_value.unwrap();println!("{}", value);let result: Result<i32, String> = Err("not valid".to_string());result.expect("failed");
}

        注意:在非生产环境或者确定不会出现错误的情况下可以使用unwrap()方法和expect()方法,但在实际项目开发中应尽量避免。

?运算符

        Rust提供了一个便捷的?运算符,用于简洁地传播错误。当Result类型变量出现在?后面时,如果它是Ok值,则解包其内部的值;如果是Err值,则从当前函数返回该错误。

        在下面的示例代码中,?操作符用于简化错误处理。如果在其前面的操作File::open和read_to_string返回Err变体,则整个表达式会立即返回该错误。这使得代码更加简洁,但也可能隐藏一些复杂的错误处理逻辑。在需要更精细控制错误处理的情况下,应该使用完整的match表达式或if let语句。

use std::fs::File;
use std::io::Read;fn read_file(filename: &str) -> Result<String, std::io::Error> {let mut file = File::open(filename)?;let mut contents = String::new();file.read_to_string(&mut contents)?;Ok(contents)
}fn main() {let result = read_file("CSDN.txt");match result {Ok(contents) => println!("content is: {}", contents),Err(e) => {println!("read file failed: {}", e);}}
}

自定义错误

        在Rust中,可以通过实现std::error::Error trait来创建自定义错误类型。这允许我们定义自己的错误类型,并能够更具体地描述程序中可能发生的错误情况。

        自定义错误类型通常包含一个或多个字段,这些字段可以包含有关错误的额外信息。通过实现Error trait,我们可以控制错误消息的格式,并且错误类型可以与其他期望Error trait的Rust错误处理机制一起工作。

        在下面的示例代码中,MyCustomError是一个简单的结构体,它包含一个描述错误的String字段。我们实现了Error trait,使得MyCustomError可以作为错误类型被使用。此外,我们还实现了fmt::Display trait,以定义错误打印时应该显示的字符串。process函数模拟了一些可能失败的操作,并在失败时返回一个MyCustomError实例。在main函数中,我们调用process函数并处理其返回的结果,并打印输出相应的信息。

use std::error::Error;
use std::fmt;// 自定义错误类型
#[derive(Debug)]
struct MyCustomError {desc: String,
}  // 实现Error trait
impl Error for MyCustomError {}// 实现Display trait
impl fmt::Display for MyCustomError {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {write!(f, "{}", self.desc)}
}fn process() -> Result<(), MyCustomError> {Err(MyCustomError {desc: "something is wrong".to_string(),})
}fn main() {match process() {Ok(()) => println!("success"),Err(e) => {println!("failed: {}", e);}  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/757537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KUKA机器人自动回原点程序

一、创建全局变量点 创建两个全局变量分别用于储存机器人的笛卡尔姿态与关节角姿态。 打开System文件夹中的config文件创建全局变量的点位。 在USER GROBALS用户自定义变量Userdefined variables下创建一个E6POS类型的点位&#xff0c;一个E6AXIS类型的点位。 二、创建回原点…

基于SpringBoot+Vue交通管理在线服务系统的开发(源码+部署说明+演示视频+源码介绍)

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。&#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精通…

React状态管理Mobx

1 https://zh.mobx.js.org/README.html 2 https://juejin.cn/post/7046710251382374413 3 https://cn.mobx.js.org/refguide/observable.html ​​mobx入门基础教程-慕课网​​ ​​Mobx学习 - 掘金​​ 十分钟入门 MobX & React ​​十分钟入门 MobX & React​​…

警惕!On Hold被踢,2本1区,5本Springer旗下,共8本SCI/SSCI被剔除!

毕业推荐 SSCI&#xff08;ABS一星&#xff09; • 社科类&#xff0c;3.0-4.0&#xff0c;JCR2区&#xff0c;中科院3区 • 13天录用&#xff0c;28天见刊&#xff0c;13天检索 SCIE&#xff1a; • 计算机类&#xff0c;6.5-7.0&#xff0c;JCR1区&#xff0c;中科院2区…

农业气象站在农业生产中的应用—气象科普

农业气象站在农业生产中发挥着至关重要的作用。它能够有效监测和记录农田环境中的各类气象要素&#xff0c;为农民提供科学、准确的气象数据&#xff0c;帮助他们更好地掌握天气变化规律&#xff0c;从而合理安排农业生产活动。 首先&#xff0c;农业气象站能够实时提供温度、…

使用 Clojure 进行 OpenCV 开发简介

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;如何将OpenCV Java 与Eclipse结合使用 下一篇&#xff1a; OpenCV4.9.0在Android 开发简介 ​警告 本教程可以包含过时的信息。 从 OpenCV 2.4.4 开始&#xff0c;OpenCV 支持…

挑战设计极限!电路仿真软件成功案例大揭秘,助您圆梦创新之路

在电子设计领域&#xff0c;电路仿真软件扮演着至关重要的角色。它们不仅能够帮助工程师们模拟和分析电路的性能&#xff0c;还能够加速设计过程&#xff0c;降低成本&#xff0c;提高产品的质量和可靠性。今天&#xff0c;让我们一起挑战设计极限&#xff0c;揭秘电路仿真软件…

Java基础---反射

什么是反射&#xff1f; 反射允许对成员变量&#xff0c;成员方法和构造方法的信息进行编程访问。 这么说可能比较抽象&#xff0c;可以简单理解为&#xff1a;反射就是一个人&#xff0c;可以把类里面的成员变量&#xff0c;成员方法&#xff0c;构造方法都获取出来。 并且可…

Springcloud智慧工地APP云综合平台源码 SaaS服务

目录 智慧工地功能介绍 一、项目人员 二、视频监控 三、危大工程 四、绿色施工 五、安全隐患 具体功能介绍&#xff1a; 1.劳务管理&#xff1a; 2.施工安全管理&#xff1a; 3.视频监控管理&#xff1a; 4.机械安全管理&#xff1a; 5.危大工程监管&#xff1a; …

ctf_show笔记篇(web入门---反序列化)

目录 反序列化 254&#xff1a;无用&#xff0c;是让熟悉序列化这个东西的 255&#xff1a;直接使$isViptrue 256&#xff1a;还是使用变量覆盖 257&#xff1a;开始使用魔法函数 258&#xff1a;将序列化最前面的过滤了&#xff0c;使用绕过 259: 这一题需要看writeup才…

windows10 WSL启动Ubuntu虚拟机,安装DolphinScheduler

文章目录 1. 启动WSL与虚拟机2. 安装Docker与DolphinScheduler容器 1. 启动WSL与虚拟机 使用管理员权限运行命令&#xff1a; Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux重启后即可创建虚拟机 在Microsoft Store中搜索Ubuntu&…

研二双9找个日常实习都找不到,哎!

投了几家日常&#xff0c;要不就面完没反应&#xff0c;要不就秒挂&#xff0c;看不透了。是最近都在忙着处理春招和暑期实习吗&#xff0c;怎么连个日常实习都找不到&#xff1f; 个人背景双9&#xff0c;lc以前刷过200道&#xff0c;最近没怎么碰过。 腾讯 3.13 一面&#xf…

给老婆整了个短剧搜索机器人APP

最近短剧挺火&#xff0c;很多群友们都在做一些资源分享&#xff0c;老胡于是基于这些资源做了个短剧搜索引擎&#xff0c;挺多朋友喜欢看的&#xff0c;我老婆也在看哈哈&#xff0c;真上头&#xff0c;废话不多说&#xff0c;上短剧机器人。 短剧机器人 直接在微信群输入&…

麒麟 V10 一键安装 Oracle 11GR2(231017)单机版

Oracle 一键安装脚本&#xff0c;演示 麒麟 V10 一键安装 Oracle 11GR2 单机版过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库 脚本第…

提升合规性!Zoho如何优化CRM产品合规性?

在企业数字化和信息化高速发展的今天&#xff0c;CRM管理系统成为越来越多企业的选择。然而&#xff0c;不是所有CRM供应商都有合规意识。合规性不应当只是一项法律规定&#xff0c;更是保证CRM供应商持续发展、赢得客户信赖以及应付监管压力的关键支撑。Zoho对企业合规性的重视…

Python探索反距离加权空间插值方法的深度

介绍 反距离加权 (IDW) 是一种广泛用于地理信息系统 (GIS) 和环境科学的空间插值技术,用于根据附近位置的值估计任何位置的缺失值。其基本原理很直观:距离兴趣点较近的位置比距离较远的位置更相似。本文深入探讨了 IDW 的方法、应用、优势和局限性,深入探讨了其在空间分析中…

招聘必备知识:求职者跟进邮件如何写?

写一封正确的招聘跟进邮件是一门艺术。在面试结束后给你的候选人发一封好的后续邮件可以为招聘工作创造奇迹&#xff0c;甚至最终入职的候选人也是如此。 与候选人保持良好的沟通&#xff0c;可以确保他们一直参与其中&#xff0c;给予他们应得的尊重和赞赏。然而&#xff0c;…

机器学习——终身学习

终身学习 AI不断学习新的任务&#xff0c;最终进化成天网控制人类终身学习&#xff08;LLL&#xff09;&#xff0c;持续学习&#xff0c;永不停止的学习&#xff0c;增量学习 用线上收集的资料不断的训练模型 问题就是对之前的任务进行遗忘&#xff0c;在之前的任务上表现不好…

HarmonyOS系统开发ArkTS常用组件按钮及参数

Button组件有两种使用方式&#xff0c;分别是不包含子组件和包含子组件两种方式。不同方式Button 组件所需的参数有所不同。 1、不包含子组件 Button(label?: string, options?: { type?: ButtonType, stateEffect?: boolean }) label为按钮上显示的文字内容options.type…

21个 JVM 技术点详解(附面试解答)

最近兄弟们面试&#xff0c;都逃不过被 JVM 问题轰炸的命运&#xff0c;为啥面试官喜欢拿 JVM 说事呢&#xff1f;V 哥认为&#xff0c;除了要问倒你&#xff0c;就是要压你薪水&#xff0c;咱绝对不能怂&#xff0c;俗话说的好&#xff1a;兵来将挡&#xff0c;水来土掩&#…