leevis.com icon indicating copy to clipboard operation
leevis.com copied to clipboard

rust错误处理

Open vislee opened this issue 1 year ago • 0 comments

概述

每个语言都有自己的错误处理,例如:C的errno、C++的try-catch、golang的error interface。 rust也有自己的错误处理,考虑自身语言的特点和几种错误处理的情况,rust使用Error这个trait结合Result这个枚举类型实现。

实现

std::result::Result

用作函数的返回,通过matchunwrapunwrap_or ? 处理结果。

pub enum Result<T, E> {
    Ok(T),
    Err(E),
}

std::error::Error

// 调试用
pub trait Debug {
    // Required method
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>;
}

// 友好输出用
pub trait Display {
    // Required method
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>;
}

pub trait Error: Debug + Display {
    // Provided methods
    fn source(&self) -> Option<&(dyn Error + 'static)> { ... }
    fn description(&self) -> &str { ... }
    fn cause(&self) -> Option<&dyn Error> { ... }
    fn provide<'a>(&'a self, request: &mut Request<'a>) { ... }
}

DebugDisplay 是 Rust 标准库中的两个不同的 trait,它们都用于定义如何将类型转换为字符串进行输出,但它们有不同的用途和语义。

  • Debug trait 用于提供类型的调试输出,通常用于开发和调试目的。它的输出应该是面向开发者的,包含足够的信息以便于调试和排查问题。
  • Display trait 用于提供类型的用户友好输出,通常用于最终用户或外部接口。它的输出应该是更加美观和易读的,适合展示给最终用户。

std::convert::From

一种类型转换为另一种类型

pub trait From<T>: Sized {
    // Required method
    fn from(value: T) -> Self;
}

thiserror

https://crates.io/crates/thiserror 该项目通过宏可以自动实现Error和From trait。

thiserror 宏库提供了几个宏,用于定义和定制自定义错误类型。以下是 thiserror 中最常用的宏及其作用:

  • #[error("...")]:定义错误的显示消息,用于实现 Display trait。
  • #[source]:标记一个字段作为当前错误的底层来源,用于std::error::Error::source方法。
  • #[from]:为从另一种错误类型到当前错误类型的转换实现 From trait,使得可以使用 ? 操作符自动转换错误类型。
  • #[backtrace]:捕获和存储错误发生时的回溯(如果平台和编译器支持),用于调试目的。

anyhow

https://crates.io/crates/anyhow 用作函数的返回类型,anyhow::Error封装了dyn std::error::Error

总结

通过实现From trait支持通过?把错误传播到调用函数,无需主动做类型转换。 通过实现Error trait的source方法,在外层调用函数中调用source显示内部错误。

参考: https://baoyachi.github.io/Rust/rust_error_handle.html

vislee avatar Apr 24 '24 10:04 vislee