问题描述
我很难理解 ?
运算符的细微差别。取以下代码:
use std::{error::Error as StdError,fmt};
#[derive(Debug)]
struct MyError(Box<dyn StdError>);
impl fmt::display for MyError {
fn fmt(&self,f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self,f)
}
}
impl StdError for MyError{}
impl From<Box<dyn StdError>> for MyError {
fn from(err: Box<dyn StdError>) -> Self {
MyError(err)
}
}
#[derive(Debug)]
struct RandomErr(String);
impl fmt::display for RandomErr {
fn fmt(&self,f)
}
}
impl StdError for RandomErr{}
fn no_custom() -> Result<(),Box<dyn StdError>> {
Err(RandomErr("hello there".to_owned()))?
}
// This fails to compile
fn custom() -> Result<(),MyError> {
Err(RandomErr("hello there".to_owned()))?
}
我认为 custom()
应该可以编译。 RandomError
是 StdError
,所以 RandomErr
应该可以转换为 MyError
,因为有一个从 StdError
转换的实现,不是吗?
解决方法
我认为 custom()
应该可以编译。 RandomError
是 StdError
,所以 RandomErr
应该可以转换为 MyError
,因为有一个从 StdError
转换的实现,不是吗?
没有。 From
中没有传递性(或任何特征,据我所知)。 Rustc 通常会按照你说的去做而不是更多以避免诸如特征解析中的组合爆炸之类的问题。
因此 C: From<B>
和 B: From<A>
不暗示/转换为 C: From<A>
,您可以编写简化的 case 并且将命中 E0277(特征不满足):
struct A;
struct B;
struct C;
impl From<A> for B {
fn from(a: A) -> Self { B }
}
impl From<B> for C {
fn from(b: B) -> Self { C }
}
fn main() {
let _: C = From::from(A);
}