31_result枚举与可恢复错误-下

1. 错误传播

我们除了在函数出处处理错误;还可以将错误返回给函数的调用者,让调用者进一步进一步处理错误,这个过程就叫做错误传播。如下示例代码

Rust 复制代码
use std::fs::File;
use std::io;
use std::io::Read;

fn read_username_from_file() -> Result<String, io::Error> {
    let f = File::open("hello.txt");

    let mut f = match f {
        Ok(file) => file,
        Err(e) => return Err(e)
    };

    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e)
    }
}

fn main() {
    let result = read_username_from_file();
}

2. ?运算符

2.1 ?运算符的使用

?运算符是传播错误的一种快捷方式。如果Result的结果是OK,OK中的值就是表达式的结果,然后继续执行程序;如果Result是Err,Err就是整个函数的返回值,就像使用了return。

函数可以简写如下

rust 复制代码
fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?;

    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

2.2 ?与from

Trait std::convert::From上的from函数,用于错误之间的转换。

被?所应用的错误,会隐式的被from函数处理,当?调用from函数时,它所接收的错误类型会被转化为当前函数返回类型所定义的错误类型。

这种情况用于:针对不同错误类型,返回同一种错误类型。只要相关的错误类型实现了转换为所返回的错误类型的from函数,就可以被转换为返回的错误类型。如同2.1中的示例。

我们可以把2.1中的代码改为链式调用,如下内容

Rust 复制代码
fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("hello.txt")?.read_to_string(&mut s)?;
    Ok(s)
}

2.3 ?运算符只能用于返回Result的函数

如果我们直接在main使用?运算符,如下代码,将会报错

Rust 复制代码
use std::fs::File;

fn main() {
    let f = File::open("hello.txt")?;
}

此时的main函数返回单元类型(),相当于什么都没返回,因此会报错。我们可以修改函数如下

rust 复制代码
use std::error::Error;
use std::fs::File;

fn main() -> Result<(), Box<dyn Error>>{
    let f = File::open("hello.txt")?;
    Ok(())
}

此时main函数返回一个Result枚举,编辑将不会报错。枚举的变体为单元类型()或者Box<dyn Error>。Box<dyn Error>是一个trait对象,此处可以简单理解为:"任意可能的错误类型"。

相关推荐
treasure14011 小时前
【复古】浅尝Django前后端不分离
前端·css·python·django·bootstrap·html·web
jay神12 小时前
基于 YOLOv8 的手势识别系统(Web 版)
前端·人工智能·python·深度学习·yolo·计算机视觉·计算机毕业设计
屏什么录12 小时前
长时间录屏中途崩溃:MP4 打不开的 6 种救回方案与参数设置
前端·音视频开发
code_Bo12 小时前
不只命令行:我把跨 Agent 会话同步做成了桌面应用
前端·javascript·后端
kyriewen12 小时前
AI 能把页面写出来,为什么改个需求就开始崩?
前端·javascript·人工智能
SomeOtherTime13 小时前
Rust 泛型与特性讲解(AI回答)
rust
涛涛ing14 小时前
2026年最值得关注的前端变化,藏在“默认值”里
前端
亿元程序员15 小时前
太牛了!这AI做出来的游戏,居然还能变现!
前端
hellice16 小时前
闪传 FlashDrop 实战:我用 300 行 Node 代码做了个「4 位取件码」临时文件中转站
前端·产品
用户08297732600516 小时前
RTX 5500 MIG 踩坑记录:切分之后模型跑不起来,排错整整一下午
前端