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<…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...
