2024 Rust现代实用教程 Error错误处理

news2024/11/6 0:53:41

文章目录

  • 一、错误处理之: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结果只能使用match
    match divide(1, 2) {
        Ok(number) => println!("{}", number),
        Err(err) => println!("{}", err),
    }

    match divide(1, 0) {
        Ok(number) => println!("{}", number),
        Err(err) => println!("{}", err),
    }

    // option
    let 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"),
    }
    // panic
    let vec = vec![1, 2, 3, 4, 5];
    vec[43]; //数组越界
}

编译及运行:

 cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running `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 run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running `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_unwind
             at /rustc/1e4f10ba6476e48a42a79b9f846a2d9366525b9e/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/1e4f10ba6476e48a42a79b9f846a2d9366525b9e/library/core/src/panicking.rs:75:14
   2: core::panicking::panic_bounds_check
             at /rustc/1e4f10ba6476e48a42a79b9f846a2d9366525b9e/library/core/src/panicking.rs:285:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index
             at /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:304:10
   4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:16:9
   5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
             at /home/wangji/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3344:9
   6: ch17_error::main
             at ./src/main.rs:43:8
   7: core::ops::function::FnOnce::call_once
             at /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 run
   Compiling ch18_question_unwrap v0.1.0 (/home/wangji/installer/rust/project/ch18_question_unwrap)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23s
     Running `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 run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/ch19_custom_err`
Error: Custom Error: CustomError
Error: MyError { detail: "CustomError" }

参考

  • 2024 Rust现代实用教程

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

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

相关文章

【Docker故障处理】Ubuntu系统下tab键无法补全问题解决

【Docker故障处理】Ubuntu系统下tab键无法补全问题解决 一、环境介绍1.1 本地环境规划1.2 本次实践说明二、故障现象三、故障分析3.1 可能的原因3.2 排错思路四、故障处理4.1 安装bash-completion4.2 下载补全脚本4.3 配置永久生效五、测试tab键补全六、总结一、环境介绍 1.1 …

若依框架-添加测试类-最新

1、在【ruoyi-admin】的pom.xml下添加依赖 <!-- 单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId><scope>test</scope></dependency><dependency>…

CSS基础概念:什么是 CSS ? CSS 的组成

什么是 CSS&#xff1f; CSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;是一种用于控制网页外观的样式表语言。通过定义样式规则&#xff0c;CSS 可以指定 HTML 页面中各个元素的显示方式&#xff0c;包括颜色、布局、字体、间距等。 与 HTML 专注…

解密RFID技术提升应急消防管理效率的过程

一、部署RFID消防应急解决策略的具体步骤 &#xff08;1&#xff09;需求探讨与战略规划阶段 深入探究&#xff1a;全面、深刻地理解消防领域在资源分配、人员跟踪、应急救援等方面的实际需求。与消防机构紧密合作&#xff0c;共同确定RFID技术的应用提升和具体实施范围。 细…

国内短剧源码短剧系统搭建小程序部署H5、APP打造短剧平台

​在当今的互联网时代&#xff0c;短剧作为一种新兴的娱乐形式&#xff0c;受到了越来越多用户的喜爱。为了提供更好的用户体验和满足用户需求&#xff0c;一个好的短剧系统需要具备多元化的功能和优质的界面设计。 本文将介绍国内短剧源码短剧系统搭建小程序部署H5、APP所需的…

使用docker安装zlmediakit服务(zlm)

zlmediakit安装 zlmediakit安装需要依赖环境和系统配置&#xff0c;所以采用docker的方式来安装不容易出错。 docker pull拉取镜像(最新) docker pull zlmediakit/zlmediakit:master然后先运行起来 sudo docker run -d -p 1935:1935 -p 80:80 -p 8554:554 -p 10000:10000 -p …

qt QDragEnterEvent详解

1、概述 QDragEnterEvent是Qt框架中用于处理拖放进入事件的一个类。当用户将一个拖拽对象&#xff08;如文件、文本或其他数据&#xff09;拖动到支持拖放操作的窗口部件&#xff08;widget&#xff09;上时&#xff0c;系统会触发QDragEnterEvent事件。这个类允许开发者在拖拽…

HarmonyOS Next星河版笔记--界面开发(3)

属性 1.1.设计资源-svg图标 需求&#xff1a;界面中展示图标→可以使用的svg图标(任意放大缩小不失真、可以改变颜色) 使用方式&#xff1a; ①设计师提供&#xff1a;基于项目的图标&#xff0c;拷贝到项目目录使用 Image($r(app.media.ic_dianpu)) .width(40) fillColor…

查找连表的倒数第k个节点

居安思危 何解&#xff1f; 1、假如有1、2、3三个节点&#xff0c;找倒数第二个&#xff0c;实际是整数第几个&#xff1f; 3-21 2 &#xff1a; 及 length - k 1 ,所以先遍历找节点长度&#xff0c;在遍历找所需节点 // 今天这不是力扣的var findNode function(head , k){…

陪玩系统源码APP中的语音聊天直播房间有哪些功能?

陪玩系统源码APP通常采用Springboot、MybatisPlus和MySQL等后端技术栈来构建后端服务。这些技术提供了强大的数据处理能力和灵活的扩展性&#xff0c;能够满足高并发、低延迟的业务需求。 陪玩系统源码线上线下家政游戏陪玩前端开发框架如uniapp&#xff08;针对Web和小程序&am…

【python】OpenCV—findContours(4.3)

文章目录 1、功能描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数5.1、cv2.Canny5.2 cv2.boxPoints 6、参考 1、功能描述 找出图片中的轮廓&#xff0c;拟合轮廓外接椭圆和外接矩阵 2、代码实现 导入必要的库&#xff0c;固定好随机种子 import cv2 as cv import …

介绍目标检测中mAP50和mAP50-95的区别

在目标检测任务中&#xff0c;mAP&#xff08;mean Average Precision&#xff09;是一个常用的性能评估指标&#xff0c;用于衡量模型在不同类别和不同IoU&#xff08;Intersection over Union&#xff09;阈值下的平均精度。mAP50和mAP50-95是mAP的两个特定版本&#xff0c;它…

三维测量与建模笔记 - 2.2 射影几何

教程中H矩阵写的有问题&#xff0c;上图中H矩阵应该是&#xff08;n1) x (m1) 共点不变性,下图中黄色方块标记的点&#xff0c;在射影变换前后&#xff0c;虽然直线的形状有所变化&#xff0c;但仍然相交于同一个点。 共线不变性&#xff0c;下图黄色标记的两个点&#xff0c;在…

【设计模式】策略模式定义及其实现代码示例

文章目录 一、策略模式1.1 策略模式的定义1.2 策略模式的参与者1.3 策略模式的优点1.4 策略模式的缺点1.5 策略模式的使用场景 二、策略模式简单实现2.1 案例描述2.2 实现代码 三、策略模式的代码优化3.1 优化思路3.2 抽象策略接口3.3 上下文3.4 具体策略实现类3.5 测试 参考资…

nuPlan最新SOTA,香港科技大学发布基于学习决策范围内的规划PlanScope

nuPlan最新SOTA&#xff0c;香港科技大学发布基于学习决策范围内的规划PlanScope Abstract 在自动驾驶的背景下&#xff0c;基于学习的方法在规划模块的开发中表现出了很大的潜力。在规划模块的训练过程中&#xff0c;直接最小化专家驾驶日志与规划输出之间的差异是一种广泛采…

String字符串 Random数字运算

Java API String 在使用String类进行字符串操作之前需要对String类进行初始化,在Java中可以通过以下两种方式对String类进行初始化 (1) 使用字符串常量 直接初始化一个String对象,具体代码如下 这是比较简化的写法 String a "abd"; (2) 使用String类的构造方法…

【Maven】——基础入门,插件安装、配置和简单使用,Maven如何设置国内源

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 引入&#xff1a; 一&#xff1a;Maven插件的安装 1&#xff1a;环境准备 2&#xff1a;创建项目 二…

王道408 DS 数据结构笔记

408 数据结构 文章目录 线性表顺序表静态分配动态分配算法设计 链表单链表双链表循环链表循环单链表循环双链表 静态链表算法设计 栈顺序栈共享栈链式栈算法设计应用 队列循环队列链队列算法设计 串顺序存储链式存储串的模式匹配 树二叉树线索二叉树树、森林树、森林的存储树和…

这款Chrome 插件,帮助任意内容即可生成二维码

前言 随着二维码的流行&#xff0c;真的是生活中越来越多的地方都有二维码了。在我们上网的时候&#xff0c;其实也可以快速的让网址生成一个二维码&#xff0c;然后我们手机扫描一下这个二维码就可以快速的在手机上打开网页了。而且&#xff0c;不仅是生成网址的二维码&#…

25届大模型秋招总结经验分享(互联网版)

个人背景&#xff1a;2硕&#xff0c;多段大厂实习&#xff0c;无a&#xff0c;学术能力拉垮 面试感受 \1. 大模型主要分为基座组和业务组&#xff0c;基座组的面试难度明显要求比业务组高&#xff0c;一般少不了各种公式推导&#xff0c;手撕源码&#xff0c;并要求对一些实…