I have the following trait:
trait MyTrait {
type A;
type B;
fn foo(a: Self::A) -> Self::B;
fn bar(&self);
}
There are other functions like bar
that must be always implemented by the user of the trait.
I would like to give foo
a default implementation, but only when the type A = B
.
Pseudo-Rust code:
impl??? MyTrait where Self::A = Self::B ??? {
fn foo(a: Self::A) -> Self::B {
a
}
}
This would be possible:
struct S1 {}
impl MyTrait for S1 {
type A = u32;
type B = f32;
// `A` is different from `B`, so I have to implement `foo`
fn foo(a: u32) -> f32 {
a as f32
}
fn bar(&self) {
println!("S1::bar");
}
}
struct S2 {}
impl MyTrait for S2 {
type A = u32;
type B = u32;
// `A` is the same as `B`, so I don't have to implement `foo`,
// it uses the default impl
fn bar(&self) {
println!("S2::bar");
}
}
Is that possible in Rust?
Extending user31601's answer and using the remark from Sven Marnach's comment, here's an implementation of the trait with additional functions using the "delegate methods" pattern:
Playground
Will this suffice?:
Rust Playground
As noted, it'll bump into problems if
MyTrait
as other methods thatMyTraitId
can't provide an implementation for.You can provide a default implementation in the trait definition itself by introducing a redundant type parameter:
This default implementation can be overridden for individual types. However, the specialized versions will inherit the trait bound from the definition of
foo()
on the trait so you can only actually call the method ifA == B
:Rust also has an unstable impl specialization feature, but I don't think it can be used to achieve what you want.