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

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<TE>{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错误处理

文章目录 一、错误处理之&#xff1a;Result、Option以及panic!宏1.Result2.Option3.panic! 二、错误处理之&#xff1a;unwrap()与?1.unwrap()2.&#xff1f;运算符 三、自定义一个Error类型参考 一、错误处理之&#xff1a;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 蜜罐提升安全性和记录攻…...

无人机拦截捕获/直接摧毁算法详解!

一、无人机拦截捕获算法 网捕技术 原理&#xff1a;抛撒特殊设计的网具&#xff0c;捕获并固定无人机。 特点&#xff1a; 适用于小型无人机。 对无人机的损害较小&#xff0c;基本不影响其后续使用。 捕获成功率较高&#xff0c;且成本相对较低。 应用实例&#xff1a;…...

后端eclipse——文字样式:UEditor富文本编辑器引入

目录 1.富文本编辑器的优点 2.文件的准备 3.文件的导入 导入到项目&#xff1a; 导入到html文件&#xff1a; ​编辑 4.富文本编辑器的使用 1.富文本编辑器的优点 我们从前端写入数据库时&#xff0c;文字的样式具有局限性&#xff0c;不能存在换行&#xff0c;更改字体…...

thinkphp6 redis 哈希存储方式以及操作函数(笔记)

逻辑&#xff1a;如果redis里没有指定表数据就进行存储再输出&#xff0c;如果有就直接输出&#xff0c;代码优化后几万条数据从数据库入redis也是三四秒的时间&#xff0c;数据以json方式存储&#xff1a;key用于数据ID 跟数据库数据ID同步&#xff0c;value用于存储整个字段包…...

「Mac畅玩鸿蒙与硬件28」UI互动应用篇5 - 滑动选择器实现

本篇将带你实现一个滑动选择器应用&#xff0c;用户可以通过滑动条选择不同的数值&#xff0c;并实时查看选定的值和提示。这是一个学习如何使用 Slider 组件、状态管理和动态文本更新的良好实践。 关键词 UI互动应用Slider 组件状态管理动态数值更新用户交互 一、功能说明 在…...

【嵌入式】STM32中的SPI通信

SPI是由摩托罗拉公司开发的一种通用数据总线&#xff0c;其中由四根通信线&#xff0c;支持总线挂载多设备&#xff08;一主多从&#xff09;&#xff0c;是一种同步全双工的协议。主要是实现主控芯片和外挂芯片之间的交流。这样可以使得STM32可以访问并控制各种外部芯片。本文…...

后端:Spring、Spring Boot-配置、定义bean

文章目录 1. 什么是Bean&#xff0c;如何配置2. 如何配置bean2.1 使用注解Bean2.2 使用注解Import 1. 什么是Bean&#xff0c;如何配置 被spring容器所管理的对象被称为bean&#xff0c;管理方式可以有纯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&#xff0c;无图片&#xff0c;没用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简介&#xff1a; Java是由Sun Microsystems公司于1995年推出的一门面向对象的高级程序设计语言&#xff0c;可以运行于多个平台&#xff0c;其…...

JVM基本结构和垃圾回收机制

一、JVM基本结构 Java虚拟机&#xff08;JVM, Java Virtual Machine&#xff09;是Java程序执行的环境&#xff0c;其基本结构可以分为以下几个主要部分&#xff1a; 类加载器子系统&#xff08;Class Loader Subsystem&#xff09;&#xff1a; 负责加载Java类文件到内存中。…...

CentOS 7 安装 ntp,自动校准系统时间

1、安装 ntp yum install ntp 安装好后&#xff0c;ntp 会自动注册成为服务&#xff0c;服务名称为 ntpd 2、查看当前 ntpd 服务的状态 systemctl status ntpd 3、启动 ntpd 服务、查看 ntpd 服务的状态 systemctl start ntpdsystemctl status ntpd 4、设置 ntpd 服务开机启…...

Spring Boot 配置文件启动加载顺序

前言 Spring Boot的启动加载顺序是一个涉及多个步骤和组件的过程。Spring Boot通过一系列默认设置简化了应用程序的配置&#xff0c;使得开发者能够快速地搭建和部署应用。为了实现这一目标&#xff0c;Spring Boot采用了一种分层和优先级机制来加载配置文件。 一、Spring Bo…...

webrtc agc2实现原理

WebRTC的AGC2&#xff08;自适应增益控制器&#xff09;是一种用于音频处理的算法&#xff0c;可以根据输入信号的强度自动调整增益&#xff0c;使输出信号的音量保持稳定。其详细原理如下&#xff1a; 噪声估计 首先&#xff0c;AGC2需要对输入信号中的噪声进行估计&#xff…...

2024.11.03 周报

一 实时超分音频同步问题: 处理方向&#xff1a; 按照胡学长的办法尝试: 前面处理视频, 将视频中音频提取出来, 将音频每隔 1-2 秒保存为一段 (这样将音频缓存在内存中) , 然后依次播放, 但是音频是44.1KHz采样率&#xff0c;每秒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 是一款高效的矢量数据库管理系统&#xff0c;支持在高并发和高调用场景下加速相似度搜索。Milvus 的 GPU 支持由 NvidiaRAPIDS 团队提供&#xff0c;可以借助各种 GPU 索引类型来优化性能。本篇将重点解析 Milvus 支持的 GPU 索引类型、适用场景及各自的性…...

Webserver(2.8)守护进程

目录 守护进程案例 守护进程案例 每隔2s获取系统时间&#xff0c;将这个时间写入到磁盘文件中 #include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include<unistd.h> #include<fcntl.h> #include<sys/time.h> #include<…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...