【发布时间】:2019-03-06 21:41:31
【问题描述】:
我有一个 String newtype ErrorMessage 用于处理原型箱中的错误。 (我知道这是一种不好的做法。我将在发布之前构建一组适当的不同错误类型。)
我需要 ErrorMessage 来实现 Error 特征,它(实际上)是空的,但要求它还实现 Display 和 Debug 特征,我已经完成了。
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,我想知道它是否可以自动将特征实现委托给String 的实现从self.0。
impl std::ops::Deref for ErrorMessage {
type Target = str;
fn deref(&self) -> &str {
&self.0
}
}
这允许我在ErrorMessage 上调用.to_string() 之类的方法,而deref coercion 将让它使用我的Deref 实现自动查找fmt 和to_string 上的self.0/@ 实现987654348@.
然而,ErrorMessage 本身实际上并不是Display 或Debug。如果我尝试直接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`
有没有办法使用Deref、DerefMut 或类似的东西来允许取消引用的值满足原始值的特征界限。我正在寻找自动的东西,作为手动编写 impl 块来委派每个块的替代方法。
【问题讨论】:
-
请注意,如果您修复 deref 实现,您的代码确实可以工作(请参阅play.rust-lang.org/…)
-
可以为ErrorMessage派生Debug,但Display还是要手动实现
-
@aochagavia 感谢您的指正!我已经修复了 deref 定义并更新了我的沙箱示例。不幸的是,这仍然不能让我摆脱
impl Debug和impl Display块。 -
您不能继承 trait 实现,但对于常见的 trait,您可以使用 derive_more crate。这回答了你的问题了吗?如果是,我可以将其发布为答案。
-
@aochagavia 感谢您的建议,很高兴知道!但这不是我想要的。