-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement multiple traits at once #1281
Comments
I don't like this, as this isn't very readable. Rather implement each at a time. |
trait Foo {
fn foo() {}
}
trait Bar: Foo {
fn foo() {}
} ? |
I think the really issue here is repeating where constraints. Typing out One solution is to make constraints on a struct apply to all impls of that struct (automatically). Another is to allow re-using generics: trait Trait {}
trait Trait2 {}
struct Test<A, B, C>(A, B, C) where A: Clone, B: Sync;
for<A, B, C> where A: Clone, B: Sync {
impl Trait for Test<A, B, C> {
}
impl Trait2 for Test<A, B, C> {
}
} |
I'd love this, but why restrict to super/sub traits? My use-case is more about implementing many small traits. I present this for your viewing pleasure. I'd love to rewrite that as: impl<Scalar, Tail> Mul<Scalar> + Div<Scalar> + Add + Sub + Neg + Zero
+ Index<usize> + IndexMut<usize>
for VectorCons<Scalar, Tail>
where Scalar: Field, Tail: Vector<Scalar=Scalar> {
type Mul::Output = Self;
type Div::Output = Self;
type Add::Output = Self;
type Sub::Output = Self;
type Neg::Output = Self;
type Index::Output = Scalar;
fn mul(self, rhs: Scalar) -> Self {
VectorCons(self.0 * rhs.clone(), self.1 * rhs)
}
fn div(self, rhs: Scalar) -> Self {
VectorCons(self.0 / rhs.clone(), self.1 / rhs)
}
fn add(self, rhs: Self) -> Self {
VectorCons(self.0 + rhs.0, self.1 + rhs.1)
}
fn sub(self, rhs: Self) -> Self {
VectorCons(self.0 - rhs.0, self.1 - rhs.1)
}
fn neg(self) -> Self {
VectorCons(-self.0, -self.1)
}
fn zero() -> Self {
VectorCons(Scalar::zero(), Tail::zero())
}
fn is_zero(&self) -> bool {
self.0.is_zero() && self.1.is_zero()
}
fn index(&self, index: usize) -> &Self::Output {
self.get(index)
.unwrap_or_else(|| {
panic!("index out of bounds: the len is {} but the index is {}",
self.len(), index);
})
}
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
let len = self.len();
self.get_mut(index)
.unwrap_or_else(|| {
panic!("index out of bounds: the len is {} but the index is {}", len, index);
})
}
} Random suggestion: for formatting's sake it'd be nice to be able to swap the impl things around a bit: impl<Scalar, Tail> for VectorCons<Scalar, Tail>: Mul<Scalar> + Div<Scalar>
+ Add + Sub + Neg + Zero
+ Index<usize> + IndexMut<usize>
where Scalar: Field, Tail: Vector<Scalar=Scalar> {
/* ... */
} or something like that. |
@Stebalien I like your suggestion from a principled POV, but more rightwards drift would make sad :( |
Hi. I like the general idea, though I would not support the "moving the impls to the end of the declaration" bit. Rather do:
(No, I'm not paid by lines of code I write 😄 ) Also: Why Four years later I don't like that idea anymore. 😎 |
A little bit of syntax sugar to make working with trait hierarchies easier.
Probably best to restrict to super-/sub-traits. E.g.,
The text was updated successfully, but these errors were encountered: