本文介绍了我可以使用 Deref<Target = Other> 吗?从其他继承 trait 实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 String newtype ErrorMessage 用于处理原型板条箱中的错误.(我知道这是一个不好的做法.我会在发布之前构建一组正确的不同错误类型.)

我需要 ErrorMessage 来实现 Error trait,它(实际上)是空的,但要求它还实现 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)}}

这很好用.但是,我最近遇到了 Deref 并且想知道它是否可以自动将 trait 实现委托给 self.0 中的 String 实现.

impl std::ops::Deref for ErrorMessage {类型目标 = str;fn deref(&self) ->&str {&self.0}}

这允许我在 ErrorMessage 和 将让它使用我的 Deref 实现来自动找到 self.0/*self 上的 fmt 和 to_string 实现.

然而,ErrorMessage 本身实际上并不是DisplayDebug.如果我尝试直接 println!format! 一个实例,我会得到一个错误,它不满足Error的界限.

fn main() ->结果{Err(ErrorMessage("hello world".to_string()))}
error[E0277]: `ErrorMessage` 没有实现 `std::fmt::Display`-->src/main.rs:2:6|2 |impl std::error::Error for ErrorMessage {}|^^^^^^^^^^^^^^^^^ `ErrorMessage` 无法使用默认格式化程序进行格式化|= help: 特性 `std::fmt::Display` 没有为 `ErrorMessage` 实现

有什么方法可以使用 DerefDerefMut 或类似的东西来允许取消引用的值满足原始值的 trait bound.我正在寻找一些自动的东西,作为手动编写 impl 块来委托每个块的替代方法.

解决方案

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

作为手动编写 impl 块来委托每个块的替代方法.

最好的办法可能是创建一个或多个宏.我个人对一流的委托支持抱有希望.>

I have a String newtype ErrorMessage that I'm using for errors in a prototype crate. (I know that this is a bad practice. I will construct a proper set of distinct error types before publication.)

I need ErrorMessage to implement the Error trait, which is (practically) empty but requires that it also implement the Display and Debug traits, which I have done.

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. However, I recently came across Deref and was wondering if it could automatically delegate trait implementations to the implementations for String from self.0.

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

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

This allows me to call methods like .to_string() on an ErrorMessage, and deref coercion will let it use my Deref implementation to automatically find the fmt and to_string implementations on self.0/*self.

However, ErrorMessage itself isn't actually Display or Debug. If I try to println! or format! an instance directly I get an error, and 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`

Is there any way to use Deref, DerefMut, or something similar to allow dereferenced values to satisfy trait bounds for the original values. I'm looking for something automatic, as an alternative to manually writing impl blocks to delegate each of them.

解决方案

No. An outer type that dereferences to an inner type does not itself implement the traits that the inner type does.

Your best bet may be to create one or more macros. I'm personally holding out hope for first-class delegation support.

这篇关于我可以使用 Deref<Target = Other> 吗?从其他继承 trait 实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 03:40