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:
#![feature(specialization)]
use std::fmt::Debug;
struct A(i32);
#[derive(Debug)]
struct B(i32);
struct Foo<T> {
data: T,
/* more fields */
}
trait Do {
fn do_something(&self);
}
impl<T> Do for Foo<T> {
default fn do_something(&self) {
/* ... */
println!("Success!");
}
}
impl<T> Do for Foo<T>
where
T: Debug,
{
fn do_something(&self) {
/* ... */
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
}
The first step is to create a trait which defines do_something(&self)
. Now, we define two impl
s of this trait for Foo<T>
: a generic "parent" impl
which is implemented for all T
and a specialized "child" impl
which is only implemented for the subset where T
implements Debug
. The child impl
may specialize items from the parent impl
. These items we want to specialize need to be marked with the default
keyword in the parent impl
. In your example, we want to specialize do_something
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With