I'd like to make the implementation of do_something
conditional based on if the generic type T
implements Debug
or not. Is there any way to do something like this?
struct A(i32);
#[derive(Debug)]
struct B(i32);
struct Foo<T> {
data: T,
/* more fields */
}
impl<T> Foo<T> {
fn do_something(&self) {
/* ... */
println!("Success!");
}
fn do_something(&self)
where
T: Debug,
{
/* ... */
println!("Success on {:?}", self.data);
}
}
fn main() {
let foo = Foo {
data: A(3), /* ... */
};
foo.do_something(); // should call first implementation, because A
// doesn't implement Debug
let foo = Foo {
data: B(2), /* ... */
};
foo.do_something(); // should call second implementation, because B
// does implement Debug
}
I think one way to do this is to create a trait where we have to define do_something(&Self)
, but I'm not sure. My code snippet is what I will try first.
Here is a solution based on the nightly feature specialization:
The first step is to create a trait which defines
do_something(&self)
. Now, we define twoimpl
s of this trait forFoo<T>
: a generic "parent"impl
which is implemented for allT
and a specialized "child"impl
which is only implemented for the subset whereT
implementsDebug
. The childimpl
may specialize items from the parentimpl
. These items we want to specialize need to be marked with thedefault
keyword in the parentimpl
. In your example, we want to specializedo_something
.