I ahve this code:
pub struct Vec2F32 {
pub x: f32,
pub y: f32,
}
impl Add<&Vec2F32> for &Vec2F32 {
type Output = Vec2F32;
fn add (self, rhs: &Vec2F32) -> Vec2F32 {
Vec2F32 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl Add<Vec2F32> for &Vec2F32 {
type Output = Vec2F32;
fn add (self, rhs: Vec2F32) -> Vec2F32 { self + &rhs }
}
impl Add<&Vec2F32> for Vec2F32 {
type Output = Vec2F32;
fn add (self, rhs: &Vec2F32) -> Vec2F32 { &self + rhs }
}
impl Add<Vec2F32> for Vec2F32 {
type Output = Vec2F32;
fn add (self, rhs: Vec2F32) -> Vec2F32 { self + &rhs }
}
Then, I need to add impls for Add, Sub, Mul, Div. This fees awfully repetitive to have four (each combo of struct vs ref).
Is there a way to reduce the repetition?
I don't see the need for any of the owned variants, you're just taking a reference, doing the addition, and discard it anyways. Let the caller just pass a reference, so you just need 1 Variant here. Unless I'm missing something ...
You can use macros. The standard library and the num crate do it that way.
2 Likes
The problem is that if we only have the ref variants, we have to write:
&(&a + &b) + &c
since (a + b)
is going to return a struct, not a ref.
Ah yeah, that's a bit of a papercut. To bad operator's aren't like methods in this regard. Still, depending on what code you'll write maybe that's a worthwhile tradeoff.
You could just make the Vec2F32
Copy
and not bother with the reference versions.
2 Likes
On a 64bit system, a ref is 64bits, so it's the same size as two f32's right? So there's no additional memory cost, and might have better memory locality.
Yes, I would also reccomend using clippy, as it catches these sorts of things, clippy is pretty nice.
1 Like