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的结果是OKOK中的值就是表达式的结果,然后继续执行程序;如果ResultErrErr就是整个函数的返回值,就像使用了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对象,此处可以简单理解为:"任意可能的错误类型"。

相关推荐
telllong2 分钟前
C++20 Modules:从入门到真香
java·前端·c++20
齐鲁大虾19 分钟前
如何在HTML/JavaScript中禁用Ctrl+C
前端·javascript·html
qq_4061761435 分钟前
深入浅出 Vue 路由:从基础到进阶全解析
前端·javascript·vue.js
陈随易1 小时前
MoonBit访谈:MoonBit开发moonclaw实现“养虾”自由
前端·后端·程序员
汀沿河1 小时前
3 LangChain 1.0 中间件(Middleware)- after_model、after_agent
前端·中间件·langchain
紫金修道1 小时前
【OpenClaw】让openclaw根据需求创造自定义skill记录
前端·javascript·chrome
周杰伦fans1 小时前
Edge浏览器 about:blank 问题修复
前端·数据库·edge
嘉琪0011 小时前
Day6 完整学习包(async/await)——2026 0318
前端·javascript·学习
SameX1 小时前
我做了个本地优先的 iOS 足迹 App,上架后才发现:最难的根本不是地图,而是让轨迹活下来
前端
踩着两条虫1 小时前
AI 驱动的 Vue3 应用开发平台 深入探究(十八):扩展与定制之集成第三方库
前端·vue.js·agent