2024 Rust现代实用教程 Error错误处理
文章目录
- 一、错误处理之:Result、Option以及panic!宏
- 1.Result
- 2.Option
- 3.panic!
- 二、错误处理之:unwrap()与'?'
- 1.unwrap()
- 2.?运算符
- 三、自定义一个Error类型
- 参考
一、错误处理之:Result、Option以及panic!宏
Rust中的错误可以分为两种
-
Recoverable error:有返回类型
(1)返回Result类型
(2)返回Option类型 -
Unrecoverable type:没有返回类型,直接崩溃
panicmacro将终止当前线程
1.Result
Result是一个枚举类型,有两个变体:0k和Err。它通常用于表示函数的执行结果,其中ok表示成功的结果,Err表示出现了错误
pub enum Result<T,E>{Ok(T),Err (E),
}
2.Option
·Option也是一个枚举类型,有两个变体:Some和None。它通常用于表示一个可能为空的值。
pub enum Option<T>{
None,
Some (T),
}
3.panic!
当程序遇到无法继续执行的错误时,可以使用panic!宏来引发恐慌。恐慌会导致程序立即终止,并显示一条错误消息。
Example:
fn divide(a: i32, b: i32) -> Result<f64, String> {if b == 0 {return Err(String::from("cannot be zero"));}let a = a as f64;let b = b as f64;Ok(a / b)
}fn find_element(array: &[i32], target: i32) -> Option<usize> {for (index, element) in array.iter().enumerate() {if (*element) == target {return Some(index);}}None
}fn main() {// 处理result结果只能使用matchmatch divide(1, 2) {Ok(number) => println!("{}", number),Err(err) => println!("{}", err),}match divide(1, 0) {Ok(number) => println!("{}", number),Err(err) => println!("{}", err),}// optionlet arr = [1, 2, 3, 4, 5];match find_element(&arr, 4) {Some(index) => println!("found in {}", index),None => println!("None"),}match find_element(&arr, 7) {Some(index) => println!("found in {}", index),None => println!("None"),}// paniclet vec = vec![1, 2, 3, 4, 5];vec[43]; //数组越界
}
编译及运行:
cargo runFinished `dev` profile [unoptimized + debuginfo] target(s) in 0.00sRunning `target/debug/ch17_error`
0.5
cannot be zero
found in 3
None
thread 'main' panicked at src/main.rs:43:8:
index out of bounds: the len is 5 but the index is 43
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
~/installer/rust/project/ch17_error master x101
RUST_BACKTRACE=1 cargo runFinished `dev` profile [unoptimized + debuginfo] target(s) in 0.00sRunning `target/debug/ch17_error`
0.5
cannot be zero
found in 3
None
thread 'main' panicked at src/main.rs:43:8:
index out of bounds: the len is 5 but the index is 43
stack backtrace:0: rust_begin_unwindat /rustc/1e4f10ba6476e48a42a79b9f846a2d9366525b9e/library/std/src/panicking.rs:665:51: core::panicking::panic_fmtat /rustc/1e4f10ba6476e48a42a79b9f846a2d9366525b9e/library/core/src/panicking.rs:75:142: core::panicking::panic_bounds_checkat /rustc/1e4f10ba6476e48a42a79b9f846a2d9366525b9e/library/core/src/panicking.rs:285:53: <usize as core::slice::index::SliceIndex<[T]>>::indexat /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:304:104: core::slice::index::<impl core::ops::index::Index<I> for [T]>::indexat /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:16:95: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::indexat /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3344:96: ch17_error::mainat ./src/main.rs:43:87: core::ops::function::FnOnce::call_onceat /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
二、错误处理之:unwrap()与’?’
1.unwrap()
注意:该方法并不安全
unwrap()是 Result 和 Option 类型提供的方法之一。它是一个简便的方法,用于获取 Ok 或 Some 的值,如果是 Err 或 None 则会引发 panic
2.?运算符
?用于简化 Result 或 Option 类型的错误传播。它只能用于返回 Result 或Option 的函数中,并且在函数内部可以像使用unwrap()一样访问 Ok 或 Some的值,但是如果是 Err 或 None 则会提前返回。
Example:
use std::num::ParseIntError;fn find_first_even(numbers: Vec<i32>) -> Option<i32> {let first_even = numbers.iter().find(|&num| num % 2 == 0)?;print!("Option");Some(*first_even)
}// 传递错误
fn parse_numbers(input: &str) -> Result<i32, ParseIntError> {let val = input.parse::<i32>()?;Ok(val)
}fn main() -> Result<(), Box<dyn std::error::Error>> {// Result<i32, &str>let result_ok: Result<i32, &str> = Ok(32);let value = result_ok.unwrap();println!("{}", value);// Result<i32, &str> 直接panic// let result_ok: Result<i32, &str> = Err("ff");// let value = result_ok.unwrap();// println!("{}", value);// 使用?let result_ok: Result<i32, &str> = Ok(100);let value = result_ok?;println!("{}", value);// 找到第一个偶数let numbers = vec![1, 3, 5];match find_first_even(numbers) {Some(_) => println!("first even 1"),None => println!("no such number"),}match parse_numbers("d") {Ok(i) => println!("parsed {}", i),Err(err) => println!("failed to parse: {}", err),}Ok(())
}
编译及运行:
cargo runCompiling ch18_question_unwrap v0.1.0 (/home/wangji/installer/rust/project/ch18_question_unwrap)Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23sRunning `target/debug/ch18_question_unwrap`
32
100
no such number
failed to parse: invalid digit found in string
三、自定义一个Error类型
1.定义错误类型结构体:创建一个结构体来表示你的错误类型,通常包含一些字段来描述错误的详细信息。
2.实现 std::fmt::Display trait:实现这个 trait以定义如何展示错误信息。这是为了使错误能够以人类可读的方式打印出来。
3.实现 std::error::Error trait:实现这个 trait以满足Rust的错误处理机制的要求。
#[derive(Debug)]
struct MyError {detail: String,
}impl std::fmt::Display for MyError {fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {write!(f, "Custom Error: {}", self.detail)}
}impl std::error::Error for MyError {fn description(&self) -> &str {&self.detail}// &String String&自动转=> &str 字符串字面量
}fn func() -> Result<(), MyError> {Err(MyError {detail: "CustomError".to_owned(),})// Ok(())
}// 等价于fn main()->Result<(), MyError>
// 所有实现std::error::Error 的东西,都可以使用Box<dyn std::error::Error>进行返回
fn main() -> Result<(), Box<dyn std::error::Error>> {match func() {Ok(_) => println!("func ok"),Err(err) => println!("Error: {}", err),}func()?;println!("oo"); //以前前面?的原因,且返回的是Err,这里则不会输出Ok(())
}
编译及运行
cargo runFinished `dev` profile [unoptimized + debuginfo] target(s) in 0.05sRunning `target/debug/ch19_custom_err`
Error: Custom Error: CustomError
Error: MyError { detail: "CustomError" }
参考
- 2024 Rust现代实用教程
相关文章:
2024 Rust现代实用教程 Error错误处理
文章目录 一、错误处理之:Result、Option以及panic!宏1.Result2.Option3.panic! 二、错误处理之:unwrap()与?1.unwrap()2.?运算符 三、自定义一个Error类型参考 一、错误处理之:Result、Option以及panic!宏 Rust中的错误可以分为…...
android 逆向破解360加固(MT管理器反编译)
1.需要准备的环境MT管理器 2.一台root手机 3,需要给app脱壳https://nop.gs/在这里脱壳 4.将脱壳的文件解压之后解压 5.用MT管理器打开需要反编译破解的app 6.然后把脱壳的classes.dex添加到破解的app里面删除原来的classes.dex 7.删除360加固的so,so在assets文件里面删除libjia…...
使用 SSH 蜜罐提升安全性和记录攻击活动
文章目录 使用 SSH 蜜罐提升安全性和记录攻击活动前言整体逻辑讲解安全最佳实践蜜罐的类型与选择数据分析与响应进一步学习资源修改 SSH 服务端口部署 FakeSSHFakeSSH 简介部署步骤记录攻击 部署 SSHSameSSHSame 简介部署步骤观察攻击行为 总结 使用 SSH 蜜罐提升安全性和记录攻…...
无人机拦截捕获/直接摧毁算法详解!
一、无人机拦截捕获算法 网捕技术 原理:抛撒特殊设计的网具,捕获并固定无人机。 特点: 适用于小型无人机。 对无人机的损害较小,基本不影响其后续使用。 捕获成功率较高,且成本相对较低。 应用实例:…...
后端eclipse——文字样式:UEditor富文本编辑器引入
目录 1.富文本编辑器的优点 2.文件的准备 3.文件的导入 导入到项目: 导入到html文件: 编辑 4.富文本编辑器的使用 1.富文本编辑器的优点 我们从前端写入数据库时,文字的样式具有局限性,不能存在换行,更改字体…...
thinkphp6 redis 哈希存储方式以及操作函数(笔记)
逻辑:如果redis里没有指定表数据就进行存储再输出,如果有就直接输出,代码优化后几万条数据从数据库入redis也是三四秒的时间,数据以json方式存储:key用于数据ID 跟数据库数据ID同步,value用于存储整个字段包…...
「Mac畅玩鸿蒙与硬件28」UI互动应用篇5 - 滑动选择器实现
本篇将带你实现一个滑动选择器应用,用户可以通过滑动条选择不同的数值,并实时查看选定的值和提示。这是一个学习如何使用 Slider 组件、状态管理和动态文本更新的良好实践。 关键词 UI互动应用Slider 组件状态管理动态数值更新用户交互 一、功能说明 在…...
【嵌入式】STM32中的SPI通信
SPI是由摩托罗拉公司开发的一种通用数据总线,其中由四根通信线,支持总线挂载多设备(一主多从),是一种同步全双工的协议。主要是实现主控芯片和外挂芯片之间的交流。这样可以使得STM32可以访问并控制各种外部芯片。本文…...
后端:Spring、Spring Boot-配置、定义bean
文章目录 1. 什么是Bean,如何配置2. 如何配置bean2.1 使用注解Bean2.2 使用注解Import 1. 什么是Bean,如何配置 被spring容器所管理的对象被称为bean,管理方式可以有纯xml文件方式、注解方式进行管理(比如注解Component)。 在Spring Boot中&…...
【Git】Git 远程仓库命令详解
目录 引言1. Git Fetch、Git Pull 和 Git Push 简介1.1 概念总结1.2 图示概念 2. 分支的概念2.1 分支定义2.2 分支的特点2.3 分支示例2.4 基本操作命令2.5 分支的使用场景 3. Git Fetch 用法3.1 基本命令3.2 获取特定分支3.3 查看更新内容3.4 使用示例3.5 适用场景 4. Git Pull…...
html简易流程图
效果图 使用htmlcssjs,无图片,没用Canvas demo: <!DOCTYPE html> <html> <head><link href"draw.css" rel"stylesheet" /><script src"draw.js" type"text/javascript"></…...
Java 入门
目录 Java简介 Java JDK开发环境配置 第一个Java程序 Java标识符与关键字 Java注释 Java常量 Java变量的定义和使用 Java简介 Java简介: Java是由Sun Microsystems公司于1995年推出的一门面向对象的高级程序设计语言,可以运行于多个平台,其…...
JVM基本结构和垃圾回收机制
一、JVM基本结构 Java虚拟机(JVM, Java Virtual Machine)是Java程序执行的环境,其基本结构可以分为以下几个主要部分: 类加载器子系统(Class Loader Subsystem): 负责加载Java类文件到内存中。…...
CentOS 7 安装 ntp,自动校准系统时间
1、安装 ntp yum install ntp 安装好后,ntp 会自动注册成为服务,服务名称为 ntpd 2、查看当前 ntpd 服务的状态 systemctl status ntpd 3、启动 ntpd 服务、查看 ntpd 服务的状态 systemctl start ntpdsystemctl status ntpd 4、设置 ntpd 服务开机启…...
Spring Boot 配置文件启动加载顺序
前言 Spring Boot的启动加载顺序是一个涉及多个步骤和组件的过程。Spring Boot通过一系列默认设置简化了应用程序的配置,使得开发者能够快速地搭建和部署应用。为了实现这一目标,Spring Boot采用了一种分层和优先级机制来加载配置文件。 一、Spring Bo…...
webrtc agc2实现原理
WebRTC的AGC2(自适应增益控制器)是一种用于音频处理的算法,可以根据输入信号的强度自动调整增益,使输出信号的音量保持稳定。其详细原理如下: 噪声估计 首先,AGC2需要对输入信号中的噪声进行估计ÿ…...
2024.11.03 周报
一 实时超分音频同步问题: 处理方向: 按照胡学长的办法尝试: 前面处理视频, 将视频中音频提取出来, 将音频每隔 1-2 秒保存为一段 (这样将音频缓存在内存中) , 然后依次播放, 但是音频是44.1KHz采样率,每秒44100次的频率. 每次间隔中程序处理的极短时间…...
Oceanbase学习之一迁移mysql数据到oceanbase
一、数据库环境 #mysql环境 root192.168.150.162 20:28: [(none)]> select version(); ---------- | version() | ---------- | 8.0.26 | ---------- 1 row in set (0.00 sec) root192.168.150.162 20:28: [(none)]> show variables like ‘%char%’; ---…...
Milvus - GPU 索引类型及其应用场景
1. 背景概述 Milvus 是一款高效的矢量数据库管理系统,支持在高并发和高调用场景下加速相似度搜索。Milvus 的 GPU 支持由 NvidiaRAPIDS 团队提供,可以借助各种 GPU 索引类型来优化性能。本篇将重点解析 Milvus 支持的 GPU 索引类型、适用场景及各自的性…...
Webserver(2.8)守护进程
目录 守护进程案例 守护进程案例 每隔2s获取系统时间,将这个时间写入到磁盘文件中 #include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include<unistd.h> #include<fcntl.h> #include<sys/time.h> #include<…...
C语言预处理指令全解析
第六章 预处理命令在c语言中,所有# 开头的指令,被称为预处理指令。gcc 编译预处理 所有的预处理指令,都要在这步处理完汇编编译连接#include包含头文件。 全局变量的声明,函数的声明, 自定义构造类型声明, …...
从零开始的Linux#2 vim编辑器
介绍vi\vim是Linux中最经典的文本编辑器,vim是vi的全面升级版本,我们后面只用vim通过vim编辑器编辑文件,需要使用命令vim 文件路径如果文件路径表示的文件不存在,那么此命令会用于编辑新文件;如果存在则编辑已有文件模…...
浏览器端音频解密技术:如何让加密音乐在本地重获新生?
浏览器端音频解密技术:如何让加密音乐在本地重获新生? 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目…...
技术指南:qobuz-dl无损音乐下载器架构解析与实战应用
技术指南:qobuz-dl无损音乐下载器架构解析与实战应用 【免费下载链接】qobuz-dl A complete Lossless and Hi-Res music downloader for Qobuz 项目地址: https://gitcode.com/gh_mirrors/qo/qobuz-dl 在数字音乐时代,音质追求者面临着一个核心矛…...
Windows热键冲突终极指南:3分钟找出偷走你快捷键的“小偷“
Windows热键冲突终极指南:3分钟找出偷走你快捷键的"小偷" 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective …...
3秒解锁微博图片溯源能力:重新定义你的信息追踪体验
3秒解锁微博图片溯源能力:重新定义你的信息追踪体验 【免费下载链接】WeiboImageReverse Chrome 插件,反查微博图片po主 项目地址: https://gitcode.com/gh_mirrors/we/WeiboImageReverse 当你在微博上看到一张惊艳的摄影作品,想要了解…...
告别Godot默认编辑器:手把手教你用VSCode配置C#开发环境(解决中文乱码)
告别Godot默认编辑器:手把手教你用VSCode配置C#开发环境(解决中文乱码)当你在Godot中编写C#脚本时,是否曾为默认编辑器的功能限制感到困扰?代码补全不够智能、调试功能简陋、界面不够友好——这些问题都会显著降低开发…...
手把手教你无损转换:把老电脑的Legacy启动盘改成UEFI+GPT(附DiskGenius操作截图)
老电脑焕新指南:从Legacy到UEFIGPT的无损迁移实战当你的老电脑开机速度越来越慢,或者被Windows 11的安装要求拒之门外时,很可能是因为它还在使用传统的Legacy启动方式和MBR分区表。本文将带你深入了解这两种启动方式的区别,并手把…...
高能物理实时触发系统:HGQ与LGN算法在FPGA上的极致优化实践
1. 项目概述:当粒子对撞遇见实时AI在大型强子对撞机(LHC)每秒数千万次的质子对撞中,CMS探测器会捕获海量的高维数据。第一级触发系统(L1T)的任务,是在3.8微秒的极短时间内,将事件率从…...
Atomic Layout测试策略:单元测试与集成测试最佳实践
Atomic Layout测试策略:单元测试与集成测试最佳实践 【免费下载链接】atomic-layout Build declarative, responsive layouts in React using CSS Grid. 项目地址: https://gitcode.com/gh_mirrors/at/atomic-layout 在现代前端开发中,构建可靠的…...
