我可以使用Deref <target>从Other继承特征实现吗?

时间:2019-03-06 21:41:32

标签: rust traits

我有一个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实现来自动找到fmtto_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块以委派每个块的方法。

1 个答案:

答案 0 :(得分:2)

  

有什么方法可以使用DerefMutimpl或类似的方法来允许被取消引用的值满足原始值的特征范围。

不。取消引用内部类型的外部类型本身不会实现内部类型所具有的特征。

  

作为手动编写{{1}}块以委派每个块的替代方法。

您最好的选择是创建一个或多个宏。我个人对documentation抱有希望。