Hi there!
I just recently, about three days ago, started learning and trying out Rust!
My programming background is nothing to impressive, basically it’s just comprised of many years of spare-time ANSI C programming until I, two years ago, went back to school and studied game programming, learning OOP and C++.
During that time I never really saw the great benefits of OOP, especially in the context of game programming where performance is paramount, and while I would use it professionally I still kept using ANSI C for all my spare-time project because it made more sense to me.
But since I found Rust I have to say that I’m quite intrigued by the safety and concurrency features, but also Rusts way of implementing OOP:ish behavior makes a lot more sense to me, and I really like the functionality and implementation of Traits over inheritance.
So, now to my request: As I said, I’m really new to Rust, and because of my education I mainly develop game related things.
So a lot of the time I tend to prefer the most performance effective solutions over solutions that trade performance for other benefits, and I also tend to write my own basic linear algebra functionality when ever I try out a new language.
I do this because linear algebra is used a lot in game development and it also seems to have a tendency to cover a lot of different aspects of a language when you implement it, so I started implementing a simple Vec2 type today, and before I get to far into my linear algebra implementation, I thought it would be good to get some pointers from more experienced Rust user about my code this far!
What I’m mostly interested in knowing is if anything that I’m doing this far could potentially be bad for performance, maybe something I do in my code have some big performance costs that I have failed to realize, or just if anything that I’m doing is exceptional stupid to do in Rust!
Thanks in advance!
use std::ops::{Index, IndexMut, Add, Sub, Mul, AddAssign, SubAssign, MulAssign};
type V2<T> = [T; 2];
#[derive(Debug)]
pub struct Vec2<T>(V2<T>);
impl<T: Copy + Mul<Output = T>> Vec2<T> {
pub fn new(x: T, y: T) -> Vec2<T> {
Vec2 {
0: ([x, y]),
}
}
pub fn length_squared(&self) -> T {
(self.0[0] * self.0[0]) * (self.0[1] * self.0[1])
}
}
impl<T> Index<usize> for Vec2<T> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.0[i]
}
}
impl<T> IndexMut<usize> for Vec2<T> {
fn index_mut(&mut self, i: usize) -> &mut T {
&mut self.0[i]
}
}
impl<T: Copy + Add<Output = T>> Add for Vec2<T> {
type Output = Vec2<T>;
fn add(self, right: Vec2<T>) -> Vec2<T> {
Vec2 {
0: ([self[0] + right[0], self[1] + right[1]]),
}
}
}
impl<T: Copy + Sub<Output = T>> Sub for Vec2<T> {
type Output = Vec2<T>;
fn sub(self, right: Vec2<T>) -> Vec2<T> {
Vec2 {
0: ([self[0] - right[0], self[1] - right[1]]),
}
}
}
impl<T: Copy + Mul<Output = T>> Mul<T> for Vec2<T> {
type Output = Vec2<T>;
fn mul(self, right: T) -> Vec2<T> {
Vec2 {
0: ([self[0] * right, self[1] * right]),
}
}
}
impl<T: Copy + AddAssign> AddAssign for Vec2<T> {
fn add_assign(&mut self, right: Vec2<T>) {
self[0] += right[0];
self[1] += right[1];
}
}
impl<T: Copy + SubAssign> SubAssign for Vec2<T> {
fn sub_assign(&mut self, right: Vec2<T>) {
self[0] -= right[0];
self[1] -= right[1];
}
}
impl<T: Copy + MulAssign> MulAssign<T> for Vec2<T> {
fn mul_assign(&mut self, right: T) {
self[0] *= right;
self[1] *= right;
}
}