Rust错误处理:Result

文章目录

Rust基础教程: 初步所有权结构体和枚举类函数进阶泛型和特征并发和线程通信cargo包管理可空类型Option
Rust进阶教程: 用宏实现参数可变的函数类函数宏

简介

Rust中没有提供类似try...catch之类的分支语句块,而是提供了Result这种数据类型,用于处理错误的返回值。和Option类似,Result的实质也是一种枚举类型

rust 复制代码
enum Result<T, E> {
   Ok(T),
   Err(E),
}

下面做一个简单的示例,用Result类型的返回值,来构造一个除法函数,并表示x/0这种问题

rust 复制代码
// res.rs
fn div_err(x:f32, y:f32) -> Result<f32, String>{
    if y==0.0{ Err("DIV BY ZERO".to_string()) } else{ Ok(x/y) }
}

fn main(){
    println!("5/3={:?}", div_err(5.0,3.0));
    println!("5/0={:?}", div_err(5.0,0.0));
}

运行结果如下

rust 复制代码
>res.exe
5/3=Ok(1.6666666)
5/0=Err("DIV BY ZERO")

Rust有一个值得注意的性质,即未处理的Result,会在编译时提出警告,比如把main函数改成下面的形式,那么编译时会给出Result必须被使用的警告。

rust 复制代码
fn main(){
    div_err(5.0,3.0);
}

错误匹配

考虑到Result的本质是枚举类型,所以其常规的处理方式,也就是使用match匹配,相应地,Result也支持un_wrap方法,当Result的返回值是Err时输出直接报错。但另一方面,Result支持多种错误的设置,所以从报错的角度来说,功能显然是更全面的。

仍以除法为例,尽管除数为0时一定要报错,但形如 x / 0 x/0 x/0和 0 / 0 0/0 0/0显然是两种不同的错误。如果为实数添加一个无穷大,那么实数域就可以映射到一个圆形上面,从而 x / 0 x/0 x/0就可以等于 ∞ \infty ∞,但 0 / 0 0/0 0/0仍然是错的。

下面就针对这两种不同的情况,为其设置错误。

rust 复制代码
fn div_err(x:f32, y:f32) -> Result<f32, String>{
    if y==0.0{
        if x==0.0{ Err("DIV ERROR".to_string())}
        else { Err("INF ERROR".to_string()) }
    } else{
        Ok(x/y)
    }
}

fn div_print(x:f32, y:f32){
    match div_err(x, y){
        Ok(res) => println!("{}/{}={}", y, x, res),
        Err(res) => println!("{}", res)
    }
}

fn main(){
    div_print(5.0, 3.0);
    div_print(5.0, 0.0);
    div_print(0.0, 0.0);
}

运行结果如下

rust 复制代码
>res.exe
3/5=1.6666666
INF ERROR
DIV ERROR
相关推荐
Asthenia041226 分钟前
Spring扩展点与工具类获取容器Bean-基于ApplicationContextAware实现非IOC容器中调用IOC的Bean
后端
bobz96544 分钟前
ovs patch port 对比 veth pair
后端
Asthenia04121 小时前
Java受检异常与非受检异常分析
后端
uhakadotcom1 小时前
快速开始使用 n8n
后端·面试·github
JavaGuide1 小时前
公司来的新人用字符串存储日期,被组长怒怼了...
后端·mysql
bobz9651 小时前
qemu 网络使用基础
后端
Asthenia04122 小时前
面试攻略:如何应对 Spring 启动流程的层层追问
后端
Asthenia04122 小时前
Spring 启动流程:比喻表达
后端
Asthenia04122 小时前
Spring 启动流程分析-含时序图
后端
ONE_Gua2 小时前
chromium魔改——CDP(Chrome DevTools Protocol)检测01
前端·后端·爬虫