Reputation: 8970
Consider the following scenario:
Do
on all the types that implement a trait CanDo
. CanDo
, some implement a trait CanDoQuickly
.Do
to be implemented in one way for those types that CanDo
, but not CanDoQuickly
, and in another way for those types that CanDoQuickly
.I know that, in Rust, we have no negative trait bounds. My intuition is that we should probably be able to use opt-in built-in to achieve this (although, I did try unsuccessfully).
I am wondering if it is at all possible, no matter the complexity of the code, to achieve what I would like to do on stable Rust. If not, is it a design choice? Is it inherently bad to want to do something like this? It sounds like such a common problem to me that I'd be very surprised to find out it's a deprecated practice.
Upvotes: 2
Views: 94
Reputation: 56822
It is possible on nightly
with the still unstable specialization
feature and a default
implementation (see also the tracking issue for specialization):
#![feature(specialization)]
trait DoIt {
fn do_it(&self);
}
impl<T> DoIt for T
where
T: CanDo,
{
default fn do_it(&self) {
self.do_impl()
}
}
impl<T> DoIt for T
where
T: CanDoQuickly,
{
fn do_it(&self) {
self.do_quickly_impl()
}
}
trait CanDo {
fn do_impl(&self) {
println!("slowly");
}
}
trait CanDoQuickly: CanDo {
fn do_quickly_impl(&self) {
println!("quickly");
}
}
struct S1;
impl CanDo for S1 {}
impl CanDoQuickly for S1 {}
struct S2;
impl CanDo for S2 {}
fn main() {
S1.do_it();
S2.do_it();
}
Upvotes: 2