微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用“?”自动转换错误自定义类型的运算符

如何解决使用“?”自动转换错误自定义类型的运算符

我很难理解 ? 运算符的细微差别。取以下代码

link to playground

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() 应该可以编译。 RandomErrorStdError,所以 RandomErr 应该可以转换为 MyError,因为有一个StdError 转换的实现,不是吗?

解决方法

我认为 custom() 应该可以编译。 RandomErrorStdError,所以 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);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。