`T.into()`有效但是`From :: from(T)`没有

neg*_*tin 3 rust

在下面的代码片段中,convert尝试将其输入转换为Box<Error>:

fn convert<T: Into<Box<Error>>>(input: T) -> Box<Error> {
    input.into() // Compiles
    // From::from(input) // Fails to compile
}
Run Code Online (Sandbox Code Playgroud)

它适用input.into(),但当使用From::from(T)它不再有效时,它需要T实现Error:

error[E0277]: the trait bound `T: std::error::Error` is not satisfied
 --> src/main.rs:4:3
  |
4 |   From::from(input)
  |   ^^^^^^^^^^ the trait `std::error::Error` is not implemented for `T`
  |
  = help: consider adding a `where T: std::error::Error` bound
  = note: required because of the requirements on the impl of `std::convert::From<T>` for `std::boxed::Box<std::error::Error>`
  = note: required by `std::convert::From::from`
Run Code Online (Sandbox Code Playgroud)

为什么要求使用时改变FromInto?使用?运营商时,这变得特别烦人:

fn convert<T: Into<Box<Error>>>(input: T) -> Result<(), Box<Error>> {
    Err(input)? // Fails to compile
}
Run Code Online (Sandbox Code Playgroud)

有没有办法用?在这些情况下正常操作,还是我不得不求助于人工matchinto

She*_*ter 9

为什么要求使用时改变FromInto

即使某些东西实现了Into,也不意味着它实现了From.例如,从实现者列表Into:

impl<T, U> Into<U> for T 
where
    U: From<T>, 

impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData
impl Into<Vec<Annotatable>> for Annotatable
impl<T> Into<Vec<T>> for ThinVec<T>
impl<T> Into<Vec<T>> for P<[T]>
Run Code Online (Sandbox Code Playgroud)

最后四种类型没有实现From,但它们确实实现了Into.(请注意,这些类型实际上是内部编译器类型,这是我们可以在文档中看到它们的错误,但对于这种情况它是一个有用的演示.)

我何时应该实现std :: convert :: From vs std :: convert :: Into?有关这两个特征的差异的更多细节.


您可以改为声明您的泛型类型实现From使用它:

fn convert<T>(input: T) -> Box<Error>
where
    Box<Error>: From<T>,
{
    From::from(input) // Fails to compile
}
Run Code Online (Sandbox Code Playgroud)

  • 然而,反之亦然:如果`U`实现`From <T>`,那么`T`*确实*实现`Into <U>`(因为[`Into`]的覆盖impl(https:/ /doc.rust-lang.org/std/convert/trait.Into.html)).这种关系的不对称可能令人困惑. (2认同)