首页 > 解决方案 > 为什么 Rust 编译器不使用 From 特征从库错误转换为我的错误?

问题描述

鉴于这个 crate 引用了另一个 crate 的错误,我通常会编写一个From实现来转换类型。

use xladd::variant::{Variant, XLAddError};
use failure::Fail;
use std::convert::TryInto;
use std::convert::From;
use std::error::Error;

#[derive(Debug, Fail)]
enum AARCError {
    #[fail(display = "F64 Conversion failure")]
    ExcelF64ConversionError,
    #[fail(display = "Bool Conversion failure")]
    ExcelBoolConversionError,
    #[fail(display = "Conversion failure")]
    ExcelStrConversionError,
}

impl From<XLAddError> for AARCError {
    fn from(err: XLAddError) -> Self {
        AARCError::ExcelF64ConversionError // Test for now
    }
}

pub fn normalize(array: Variant, min: Variant, max: Variant, scale: Variant) -> Result<Variant, AARCError> {
    let min: f64 = min.try_into().map_err(|e| AARCError::from(e))?;
    Ok(Variant::from_str("foo"))
}

但在这种情况下,我得到一个错误:

error[E0277]: the trait bound `basic_stats::AARCError: std::convert::From<!>` is not satisfied
  --> src\basic_stats.rs:24:48
   |
24 |     let min: f64 = min.try_into().map_err(|e| AARCError::from(e))?;
   |                                               ^^^^^^^^^^^^^^^ the trait `std::convert::From<!>` is not implemented for `basic_stats::AARCError`
   |
   = help: the following implementations were found:
             <basic_stats::AARCError as std::convert::From<xladd::variant::XLAddError>>
   = note: required by `std::convert::From::from`

我不明白这个From<!>特征是什么,并且试图实现类似的东西会给未命名的类型带来错误。

我应该怎么做才能让 Rust 将外部 crate 的错误转换为我的错误?

标签: error-handlingrust

解决方案


我不明白这个From<!>特征是什么,并且试图实现类似的东西会给未命名的类型带来错误。

!“从不”无人居住的类型;没有可能值的类型。

如果 aResult具有!其错误类型,则意味着操作不会失败。无法将其转换为其他错误类型,因为错误值一开始就不存在。

never 类型目前是一个实验性功能,需要每晚构建 Rust。因此,它可能有一些粗糙的边缘,并且不像它应该的那样符合人体工程学。例如,我希望最终功能为所有使用关联类型From<T>实现的类型提供一揽子实现。不必处理不可能发生的错误应该很容易。TryFrom<T>Error = !

要解决您当前的问题,您可以将该错误映射到unreachable!(). 这种方法的唯一问题是前向兼容性——如果第三方 crate 稍后引入了一个可访问的错误,那么您的代码将有一个未处理的错误,并且没有编译时错误来保护您。!这可能是尚未稳定的部分原因。


推荐阅读