如何检查错误类型是否与 Rust 中的特定错误类型匹配?

San*_*jay 3 rust

所以我有这个自定义错误,

use std::fmt;

#[derive(Debug)]
pub enum XError {
  TagNotFound,
}

impl std::error::Error for XError {}

impl fmt::Display for XError {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self {
      XError::TagNotFound => write!(f, "couldn't find tag"),
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个函数pub fn validate() -> Result<String, Box<dyn std::error::Error>>

现在在我的测试中,如何检查validateis返回的错误XError::TagNotFound

我尝试做,

let b = validate(param)
  .unwrap_err()
  .downcast_ref::<XError::TagNotFound>();
Run Code Online (Sandbox Code Playgroud)

但我明白了expected type, found variant "XError::TagNotFound" not a type

Sve*_*ach 8

XError::TagNotFound正如错误消息所述,您的代码的问题在于这不是一种类型。它是枚举的一个变体XError

您有一个Box<dyn Error>,并且您想检查该错误是否是XError::TagNotFound。该检查包括两个步骤:

  1. 沮丧从Box<dyn Error>XError
  2. 检查是否XError沮丧XError::TagNotFound

步骤 1 可以使用 执行my_error.downcast_ref::<XError>(),这将返回一个Option<&XError>. 步骤 2 是正常的模式匹配,可以使用if letmatchmatches!()宏来执行,无论您喜欢什么。这是一种选择:

if let Some(&XError::TagNotFound) = my_error.downcast_ref::<XError>() {
    // handle error
}
Run Code Online (Sandbox Code Playgroud)

在单元测试中,使用matches!()宏可能更合适:

assert!(matches!(my_error.downcast_ref::<XError>(), Some(&XError::TagNotFound));
Run Code Online (Sandbox Code Playgroud)