最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust 錯誤處理的黃金搭檔(thiserror和anyhow)

 更新時間:2026年06月17日 10:04:25   作者:Rust研習(xí)社  
本文主要介紹了Rust 錯誤處理的黃金搭檔(thiserror和anyhow),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在 Rust 開發(fā)中,錯誤處理是不可或缺的核心環(huán)節(jié),但手動實現(xiàn)錯誤相關(guān) trait 往往會產(chǎn)生大量的樣板代碼。而為了解決這些樣板代碼,那就不得不提到兩個主流的 Rust 錯誤處理庫 thiserroranyhow 了,現(xiàn)在,我們一起來看看它們解決了什么樣的問題。

簡化自定義錯誤

在其他語言中,自定義錯誤非常簡單,以 Go 為例,只需要實現(xiàn) error 接口即可:

import "fmt"

type NotFoundError struct {
    Resource string
}

func (e NotFoundError) Error() string {
    return fmt.Sprintf("%s not found", e.Resource)
}

而在 Rust 中,自定義錯誤就比較麻煩了,需要手動實現(xiàn) Error、Display 和 Debug 這三個特征。如果需要支持錯誤自動轉(zhuǎn)換,即適配 ? 操作符,還需要額外實現(xiàn) From 特征:

use std::error::Error;
use std::{fmt, io, num::ParseIntError};

#[derive(Debug)]
enum MyError {
    Io(io::Error),
    Parse(ParseIntError),
    Custom(String),
}

// 實現(xiàn) Display 特征
impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            MyError::Io(e) => write!(f, "IO 錯誤: {}", e),
            MyError::Parse(e) => write!(f, "解析錯誤: {}", e),
            MyError::Custom(s) => write!(f, "自定義錯誤: {}", s),
        }
    }
}

// 實現(xiàn) Error 特征,標(biāo)記該類型為錯誤類型
impl Error for MyError {}

// 實現(xiàn) From 特征,支持錯誤自動轉(zhuǎn)換
impl From<io::Error> for MyError {
    fn from(e: io::Error) -> Self {
        MyError::Io(e)
    }
}

impl From<ParseIntError> for MyError {
    fn from(e: ParseIntError) -> Self {
        MyError::Parse(e)
    }
}

可以看到,僅是定義一個簡單的自定義錯誤枚舉,就需要編寫大量的樣板代碼。而 thiserror 庫則通過宏解決了這一問題。它能在編譯期自動生成上述所有樣板代碼,讓我們專注于錯誤本身的定義。

我們用 thiserror 來改寫上面的示例,實現(xiàn)如下:

use std::{io, num::ParseIntError};
use thiserror::Error;

#[derive(Error, Debug)] 
enum MyError {
    // 定義 Display 輸出格式,{0} 引用變體第一個字段
    #[error("IO 錯誤: {0}")]
    // #[from] 自動實現(xiàn) From 特征
    Io(#[from] io::Error),

    #[error("解析錯誤: {0}")]
    Parse(#[from] ParseIntError),

    #[error("自定義錯誤: {0}")]
    Custom(String),
}

需要注意的是,thiserror 是基于宏實現(xiàn),所有代碼生成都在編譯期完成,運行時零開銷,不會對程序性能帶來影響。因此,在需要自定義錯誤類型的場景中,可以大膽的使用 thiserror。

簡化通用錯誤處理

在實際開發(fā)中,我們常常會遇到函數(shù)返回多種不同錯誤類型的場景。此時有兩種處理思路:一是定義全局自定義錯誤枚舉,也就是上一章節(jié)的方案,可以通過 thiserror 簡化。二是使用 Box<dyn Error> 作為錯誤返回類型,無需單獨定義錯誤枚舉。

use std::error::Error;
use std::fs;

fn read_and_parse(path: &str) -> Result<i32, Box<dyn Error>> {
    let content = fs::read_to_string(path)?;
    let num: i32 = content.trim().parse()?;
    Ok(num)
}

先簡單了解下 Box<dyn Error>,由于所有的錯誤類型都實現(xiàn) Error 特征,dyn Error 作為動態(tài)派發(fā)的特征對象,所以可以兼容所有錯誤類型。

然而由于 dyn Error 是不定長類型(DST),無法直接存儲在棧上,因此需要用 Box<T> 智能指針將其分配到堆上。

最后是標(biāo)準(zhǔn)庫中已為所有實現(xiàn) Error 特征的類型實現(xiàn)了 From 轉(zhuǎn)換,因此可以直接使用 ? 操作符自動轉(zhuǎn)換錯誤類型。標(biāo)準(zhǔn)庫實現(xiàn)大致如下:

impl<E: Error + 'static> From<E> for Box<dyn Error> {
    fn from(err: E) -> Self {
        Box::new(err)
    }
}

搞懂了 Box<dyn Error> 后,現(xiàn)在我們就可以講 anyhow 了,anyhow 的底層實現(xiàn)是:

Box<dyn Error + Send + Sync + 'static>

不難看出,anyhow 是 Box<dyn Error> 的增強版,具體如下:

簡潔的類型別名

anyhow 提供 anyhow::Result<T> 類型別名,簡化代碼:

use anyhow::Result;

fn main() -> Result<()> {
    Ok(())
}

攜帶業(yè)務(wù)上下文

anyhow 內(nèi)置的 context 和 with_context 方法,它們?yōu)殄e誤添加上下文:

use anyhow::{Context, Result};
use std::fs;

fn read_and_parse(path: &str) -> Result<i32> {
    let content = fs::read_to_string(path)?;
    let num: i32 = content.trim().parse()?;
    Ok(num)
}

fn main() -> anyhow::Result<()> {
    let content = fs::read_to_string("config.json")
        .context("讀取配置文件失敗")?;
    
    println!("{}", content);
    
    Ok(())
}

// Output:
// Error: 讀取配置文件失敗

// Caused by:
//     No such file or directory (os error 2)

支持多線程與異步

Box<dyn Error> 未約束 Send + Sync,所以在多線程或異步場景下時會直接報錯。而 anyhow 強制約束了 Send + Sync,開箱即用,完全兼容多線程與異步場景:

use std::thread;

fn do_work() -> anyhow::Result<()> {
    Err(anyhow::anyhow!("something wrong"))
}

fn main() {
    let handle = thread::spawn(|| do_work());

    let result = handle.join().unwrap();

    match result {
        Ok(_) => println!("success"),
        Err(e) => println!("error: {:#}", e),
    }
}

// Output:
// error: something wrong

結(jié)語

在這篇文章中,我們介紹了 thiserror 和 anyhow 的使用方法,同時講解了它們的設(shè)計初衷,解決 Rust 原生錯誤處理的哪些痛點。學(xué)習(xí)技術(shù)時,知其然更要知其所以然,理解它們?yōu)槭裁创嬖?,才能在實際開發(fā)中靈活運用,選擇最適合的方案。

到此這篇關(guān)于Rust 錯誤處理的黃金搭檔(thiserror和anyhow)的文章就介紹到這了,更多相關(guān)Rust 錯誤處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程

    Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程

    本文主要介紹了Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • 前端基于Rust實現(xiàn)的Wasm進行圖片壓縮的技術(shù)文檔(實現(xiàn)方案)

    前端基于Rust實現(xiàn)的Wasm進行圖片壓縮的技術(shù)文檔(實現(xiàn)方案)

    在現(xiàn)代Web開發(fā)中,利用Rust編寫的圖片壓縮代碼可以編譯成WebAssembly(Wasm)模塊,Rust的內(nèi)存安全特性和Wasm的跨平臺能力,使得這種方案既高效又安全,對Rust?Wasm圖片壓縮實現(xiàn)方案感興趣的朋友一起看看吧
    2024-09-09
  • Rust安裝的圖文教程

    Rust安裝的圖文教程

    本文主要介紹了Rust安裝的圖文教程,文中通過圖文示例介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • Rust中箱、包和模塊的學(xué)習(xí)筆記

    Rust中箱、包和模塊的學(xué)習(xí)筆記

    Rust中有三個重要的組織概念:箱、包、模塊,本文主要介紹了Rust中箱、包和模塊的學(xué)習(xí)筆記,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • rust文件讀寫的實現(xiàn)示例

    rust文件讀寫的實現(xiàn)示例

    Rust語言提供了強大的文件讀寫庫,使得開發(fā)者可以更加方便地進行文件操作,并且其安全性可以有效避免文件操作中可能出現(xiàn)的風(fēng)險,本文就來詳細的介紹了rust文件讀寫的實現(xiàn)示例,感興趣的可以了解一下
    2023-12-12
  • Tauri?打開本地文件踩坑分析解決

    Tauri?打開本地文件踩坑分析解決

    這篇文章主要為大家介紹了Tauri?打開本地文件踩坑分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • rust將bitmap位圖文件另存為png格式的方法

    rust將bitmap位圖文件另存為png格式的方法

    通過添加依賴,轉(zhuǎn)換函數(shù)和單元測試操作步驟來解決將bitmap位圖文件另存為png格式文件,本文通過實例代碼給大家介紹的非常詳細,對rust bitmap位另存為png格式的操作方法感興趣的朋友一起看看吧
    2024-03-03
  • Rust搭建webserver的底層原理與應(yīng)用實戰(zhàn)技巧

    Rust搭建webserver的底層原理與應(yīng)用實戰(zhàn)技巧

    本文介紹Rust在HTTP編程中的應(yīng)用,涵蓋協(xié)議基礎(chǔ)、標(biāo)準(zhǔn)庫與第三方庫(如hyper、reqwest)的使用,以及多線程服務(wù)器和線程池的實現(xiàn)與關(guān)閉機制,展示Rust在性能、安全和并發(fā)方面的優(yōu)勢,感興趣的朋友跟隨小編一起看看吧
    2025-06-06
  • 教你使用RustDesk?搭建一個自己的遠程桌面中繼服務(wù)器

    教你使用RustDesk?搭建一個自己的遠程桌面中繼服務(wù)器

    這篇文章主要介紹了RustDesk?搭建一個自己的遠程桌面中繼服務(wù)器,主要包括服務(wù)端安裝和客戶端配置方法,配置好相關(guān)操作輸入控制碼即可發(fā)起遠程或文件傳輸,本文通過圖文給大家講解的非常詳細,需要的朋友可以參考下
    2022-08-08
  • Rust 數(shù)據(jù)分析利器polars用法詳解

    Rust 數(shù)據(jù)分析利器polars用法詳解

    這篇文章主要介紹了Rust 數(shù)據(jù)分析利器polars用法詳解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-08-08

最新評論

乌拉特后旗| 定西市| 芒康县| 湟源县| 全南县| 正宁县| 姜堰市| 乃东县| 方城县| 商丘市| 昌江| 饶阳县| 临夏市| 聊城市| 蕲春县| 普定县| 长岭县| 兴海县| 和田县| 阆中市| 喀喇沁旗| 文山县| 夏津县| 乐亭县| 枣庄市| 盐亭县| 云南省| 井陉县| 山西省| 阳泉市| 岳阳市| 东兴市| 遵义市| 瓦房店市| 施甸县| 石渠县| 含山县| 新闻| 宜昌市| 固始县| 佛坪县|