Vector calculation in Rust Hi I am trying to get into Rust by implementing a small library for vector calculations. 

I am mainly asking to point out whether I chose a valid approach. I also am interested in comments on the overall details I might have missed or got the wrong way.

So for my Vec3 implementation I basically declared a custom type which is an array of length 3. Afterwards I am simply implementing Traits for this type. For now I only implemented it for f32.

pub type Vec3&lt;T = f32&gt; = [T; 3];

pub trait Vector3&lt;T&gt; {
    /// Creates a new Vec3 with its values initialized to `[0.0, 0.0, 0.0]`.
    fn new() -&gt; Self;

    /// Creates a new `Vec3` based on the given `x`, `y` and `z` values.
    fn from_values(x: f32, y: f32, z: f32) -&gt; Vec3&lt;T&gt;;

    /// Calculates the scalar dot product of two `Vec3`'s.
    fn dot(a: Vec3&lt;T&gt;, b: Vec3&lt;T&gt;) -&gt; f32;

    /// Performs multiplication between two `Vec3`.
    fn multiply(self, a: Vec3) -&gt; Vec3;

    /// Calculates the sum of two `Vec3` components.Vec3
    fn add(self, a: Vec3) -&gt; Vec3;

    /// Scales a `Vec3` by a scalar value.
    fn scale(self, x: f32) -&gt; Vec3;
}

impl Vector3&lt;f32&gt; for Vec3&lt;f32&gt; {
    /// Creates a new Vec3 with its values initialized to `[0.0, 0.0, 0.0]`.
    ///
    /// ```
    /// use glMatrix_rs::vec3::*;
    ///
    /// let result = Vec3::new();
    /// assert_eq!([0.0, 0.0, 0.0], result);
    /// ```
    fn new() -&gt; Vec3&lt;f32&gt; {
        [0.0, 0.0, 0.0]
    }

    /// Creates a new `Vec3` based on the given `x`, `y` and `z` values.
    ///
    /// ### Arguments
    ///
    /// * `x` - The first vector component.
    /// * `y` - The second vector component.
    /// * `z` - The third vector component.
    ///
    /// ```
    /// use glMatrix_rs::vec3::*;
    ///
    /// let result = Vec3::from_values(0.0, 1.0, 2.0);
    /// assert_eq!([0.0, 1.0, 2.0], result);
    /// ```
    fn from_values(x: f32, y: f32, z: f32) -&gt; Vec3 {
        [x, y, z]
    }

    /// Calculates the scalar dot product of two `Vec3`'s.
    ///
    /// ### Arguments
    ///
    /// * `a` - The first vector for `dot` calculation.
    /// * `b` - The second  vector for `dot` calculation.
    ///
    /// ```
    /// use glMatrix_rs::vec3::*;
    /// let a = Vec3::from_values(2.0, 2.0, 2.0);
    /// let b = Vec3::from_values(2.0, 2.0, 2.0);
    /// assert_eq!(12.0, Vec3::dot(a, b));
    /// ```
    fn dot(a: Vec3, b: Vec3) -&gt; f32 {
        a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
    }

    /// Performs multiplication between two `Vec3`.
    ///
    /// ### Arguments
    /// 
    /// * `a` - Vector by which `self` will be multiplied.
    ///
    /// ```
    /// use glMatrix_rs::vec3::*;
    /// let mut out = Vec3::new();
    /// let a = Vec3::from_values(1.0, 2.0, 3.0);
    /// let b = Vec3::from_values(2.0, 2.0, 2.0);
    /// assert_eq!([2.0, 4.0, 6.0], a.multiply(b));
    /// ```
    fn multiply(self, a: Vec3) -&gt; Vec3 {
        [self[0] * a[0], self[1] * a[1], self[2] * a[2]]
    }

    /// Calculates the sum of two `Vec3` components.Vec3
    ///
    /// ### Arguments
    /// 
    /// * `a` - Vector which will be added to `self`.
    ///
    /// ```
    /// use glMatrix_rs::vec3::*;
    /// let x = Vec3::from_values(1.0, 2.0, 3.0);
    /// let a = Vec3::from_values(3.0, 2.0, 1.0);
    /// assert_eq!([4.0, 4.0, 4.0], x.add(a));
    /// ```
    fn add(self, a: Vec3) -&gt; Vec3 {
        [self[0] + a[0], self[1] + a[1], self[2] + a[2]]
    }

    /// Scales a `Vec3` by a scalar value.
    ///
    /// ### Arguments
    /// 
    /// * `x` - Scalar value by which the vector will be scaled. 
    ///
    /// ```
    /// use glMatrix_rs::vec3::*;
    /// let a = Vec3::from_values(1.0, 2.0, 3.0);
    /// assert_eq!([2.0, 4.0, 6.0], a.scale(2.0));
    /// ```
    fn scale(self, x: f32) -&gt; Vec3 {
        [self[0] * x, self[1] * x, self[2] * x]
    }
}


You can clone, build and test it any time from my GitHub repository.
My first recommendation is to use std::ops. Try writing implementations of ops::Add for addition,  ops::Mul&lt;Vec3&lt;T&gt;&gt; for cross product, and ops::Mul&lt;T&gt; for scaler-vector multiplication. Not only does implementing these standard traits make your code more interoperable with other Rust code, but it also gives you operator overloading, so you can use + and * on your vectors.

Second, I would question the user of the trait Vector3&lt;f32&gt;. Why do you need a trait? I would just put your operations in the implementation of Vec3&lt;T&gt; itself

impl &lt;T&gt; Vec3&lt;T&gt; {

// ... methods ...

}


Looking forward to seeing your completed code. This will even more interesting once you get generics working.