2017-02-19 8 views
8

デバッグを支援するために作成するほとんどの構造体については、#[derive(Debug)]には良い習慣と考えられます。しかし、構造体にDebugのない型がある場合、これは不可能です。しかし、もしその特性が私のコントロール下にあるのであれば、デバッグメッセージにその特性の実装をユーザーに表示させるためにできることはありますか?どのようにしてデフォルトのデバッグ実装を提供しますか?

私は私の形質を実装する人も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) } 

BDebugを実装していないとき、私は最初の出力をしたいです。

+1

[特性に親形質を実装する](https://github.com/rust-lang/rfcs/issues/1024)のようなサウンドは、あなたの特性のためのデフォルトのインプットである 'Debug' 。 – Lukazoid

答えて

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); 
} 

注これは上の負担を課すことコンテナ。

関連する問題