Почему компилятор Rust не преобразует ошибку библиотеки в мою ошибку, используя черту From? - PullRequest
0 голосов
/ 25 ноября 2018

Учитывая, что этот ящик ссылается на ошибку из другого ящика, я обычно пишу реализацию 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 преобразовал ошибки внешнего ящика вмои?

1 Ответ

0 голосов
/ 25 ноября 2018

Я не понимаю, что такое черта From<!>, и попытка реализовать нечто подобное приводит к ошибке для неназванных типов.

! - это "никогда " или необитаемый тип;тип, который не имеет возможных значений.

Если Result имеет ! для своего типа ошибки, это означает, что операция не может быть неудачной.Невозможно преобразовать его в какой-либо другой тип ошибки, потому что значение ошибки не может существовать в первую очередь.

В настоящее время тип никогда не является экспериментальной функцией, требующей ночной сборки Rust.Как таковой, он, вероятно, имеет несколько шероховатых краев и не так эргономичен, как мог бы быть.Например, я ожидаю, что последняя функция предоставит полную реализацию From<T> для всех типов, которые реализуют TryFrom<T> со связанным типом Error = !.Это должно быть сделано легко, чтобы не обрабатывать ошибку, которая не может произойти.

Чтобы исправить вашу непосредственную проблему, вы можете сопоставить эту ошибку с unreachable!().Единственная проблема с этим подходом - это прямая совместимость - если в стороннем ящике позже появится достижимая ошибка, то в вашем коде будет необработанная ошибка и не будет ошибки времени компиляции, чтобы защитить вас.Вероятно, это часть того, почему ! еще не стабилизирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...