我可以使用Deref吗? 继承其他的特质实现?

问题描述 投票:3回答:1

我有一个String newtype ErrorMessage,我正在使用原型板条箱中的错误。 (我知道这是一个不好的做法。我会在发布之前构造一组适当的错误类型。)

我需要ErrorMessage来实现Error特性,它(实际上)是空的,但要求它也实现了DisplayDebug特征,我已经完成了。

pub struct ErrorMessage(pub String);
impl std::error::Error for ErrorMessage {}
impl std::fmt::Display for ErrorMessage {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}
impl std::fmt::Debug for ErrorMessage {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

This works fine。然而,我最近遇到了Deref,并想知道它是否可以自动将特征实现委托给Stringself.0实现。

impl std::ops::Deref for ErrorMessage {
    type Target = str;

    fn deref(&self) -> &str {
        &self.0
    }
}

这允许我在.to_string()上调用类似ErrorMessage的方法,而deref coercion将允许它使用我的Deref实现自动在fmt / to_string上找到self.0*self实现。

然而,ErrorMessage本身实际上不是DisplayDebug。如果我直接尝试println!format!实例,我会得到一个错误,并且it doesn't satisfy the bounds for Error

fn main() -> Result<(), ErrorMessage> {
    Err(ErrorMessage("hello world".to_string()))
}
error[E0277]: `ErrorMessage` doesn't implement `std::fmt::Display`
 --> src/main.rs:2:6
  |
2 | impl std::error::Error for ErrorMessage {}
  |      ^^^^^^^^^^^^^^^^^ `ErrorMessage` cannot be formatted with the default formatter
  |
  = help: the trait `std::fmt::Display` is not implemented for `ErrorMessage`

有没有办法使用DerefDerefMut或类似的东西允许解除引用的值来满足原始值的特征边界。我正在寻找一些自动的东西,作为手动编写impl块来代表它们的替代方法。

rust traits
1个回答
2
投票

有没有办法使用DerefDerefMut或类似的东西允许解除引用的值来满足原始值的特征边界。

否。解除内部类型的外部类型本身并不实现内部类型所具有的特征。

作为手动编写impl块以替代它们的替代方法。

您最好的选择可能是创建一个或多个宏。我个人对first-class delegation support抱有希望。

© www.soinside.com 2019 - 2024. All rights reserved.