首页 > 解决方案 > 如何检查错误类型是否与 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"),
    }
  }
}

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

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

我试着做,

let b = validate(param)
  .unwrap_err()
  .downcast_ref::<XError::TagNotFound>();

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

标签: rust

解决方案


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

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

  1. 如果可能,从 向下Box<dyn Error>转换。XError
  2. 检查是否向下转换XErrorXError::TagNotFound.

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

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

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

assert!(matches!(my_error.downcast_ref::<XError>(), Some(&XError::TagNotFound));

推荐阅读