'How do you implement a trait for T where T: Foo OR Bar
In rust, you can automatically implement a trait for any type that implements some other combination of traits. Ie:
impl<T: Foo + Bar> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
What I'm trying to do is define a relationship where Foo
and Bar
are both enough to implement SomeTrait
by themselves. Basically, something like this:
impl<T: Foo> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
impl<T: Bar> SomeTrait for T {
some_function(&self) {
/*...*/
}
}
This won't compile, because you're implementing SomeTrait
for T
twice and the compiler can't possibly know what to do in the case where T: Foo + Bar
, but it'd be really nice to be able to do this.
Is there some way to "abstract" around this problem so that I can call some_function()
on a T
that implements Foo
OR Bar
? Or am I stuck with having to pick only one implementation?
Solution 1:[1]
If you use nightly, you can use the marker_trait_attr
feature. It allows you to have overlapping impls for a trait that has the attribute #[marker]
. Note that the trait should have no associated items - it must be empty.
Thus, you can define a marker trait FooOrBar
(I made it in a private module so it's sealed and people cannot implement it manually):
#![feature(marker_trait_attr)]
mod private {
#[marker]
pub trait FooOrBar {}
impl<T: super::Foo> FooOrBar for T {}
impl<T: super::Bar> FooOrBar for T {}
}
And then implement the trait SomeTrait
for any type that implements FooOrBar
:
impl<T: private::FooOrBar> SomeTrait for T {
fn foo(&self) { /* ... */ }
}
For stable, unfortunately, I don't think there is a way but a redesign.
Solution 2:[2]
Turns out that there are some safety properties that need some serious thought before this can be a feature.
The only real way to get close to what I was after is using the specialisation feature, which is unstable for a number of reasons that are a bit beyond me.
Unfortunately, this does seem to mean that traits aren't quite as powerful as I originally thought, but there should always be other ways to approach this kind of scenario.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Chayim Friedman |
Solution 2 | nebulaeandstars |