对于您创建的大多数结构来说,#[derive(Debug)]
被认为是一种良好的做法,有助于调试。但是,如果您的struct包含没有Debug
的类型(如traits),则无法执行此操作。但是,如果这个特性在我的控制之下,那么我能做些什么才能让用户能够做到这一点。所述特征的实现显示在调试消息中?
我可以要求实施我的特质的人也实施Debug
,但我不想添加任意要求:
trait MyTrait: Debug { ... }
我可以为我的特性实施Debug
:
trait MyTrait { ... }
impl Debug for MyTrait {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "MyTrait {{ ... }}")
}
}
这并不允许实现覆盖Debug
- 它几乎就像功能不是虚拟的一样。我怎样才能做到这一点?
use std::fmt;
use std::fmt::{ Formatter, Debug };
#[derive(Debug)]
struct A {
a: Box<Data>,
}
trait Data {}
impl Debug for Data {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Data{{ ... }}")
}
}
#[derive(Debug)]
struct B(i32);
impl Data for B {}
fn main() {
let a = A{ a: Box::new(B(42)) };
println!("{:?}", a);
}
输出:
A { a: Data{ ... } }
我想要的是什么:
A { a: B(42) }
我只希望B
未实现Debug
时的第一个输出。
答案 0 :(得分:5)
您可以创建自己的特质方法。希望增强调试和实现Debug
的类型可以委派:
use std::fmt;
use std::fmt::{ Formatter, Debug };
#[derive(Debug)]
struct Container(Box<Data>);
trait Data {
fn debug_fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Data {{ ... }}")
}
}
impl Debug for Data {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.debug_fmt(f)
}
}
#[derive(Debug)]
struct Overrides(i32);
impl Data for Overrides {
fn debug_fmt(&self, f: &mut Formatter) -> fmt::Result {
self.fmt(f)
}
}
#[derive(Debug)]
struct Defaults(i32);
impl Data for Defaults {}
fn main() {
let a = Container(Box::new(Overrides(42)));
println!("{:?}", a);
let a = Container(Box::new(Defaults(42)));
println!("{:?}", a);
}
需要不稳定的专业化功能的替代解决方案:
#![feature(specialization)]
use std::fmt;
use std::fmt::{Formatter, Debug};
struct Container<D>(Box<D>) where D: Data;
impl<D> Debug for Container<D>
where D: Data
{
default fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Container(Data {{ ... }})")
}
}
impl<D> Debug for Container<D>
where D: Data + Debug
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Container({:?})", self.0)
}
}
trait Data {}
#[derive(Debug)]
struct Overrides(i32);
impl Data for Overrides {}
struct Defaults(i32);
impl Data for Defaults {}
fn main() {
let a = Container(Box::new(Overrides(42)));
println!("{:?}", a);
let a = Container(Box::new(Defaults(42)));
println!("{:?}", a);
}
请注意,这会给容器带来负担。