Hi,
I am kind of lost here. I've gotten so used to a one style templatting in C++ that Rust solution seams to me as very difficult to grasp, but I must get rid of my old habits and learn new ones. In one of my previous posts I asked for a concrete advice but realized there is so much ahead of me, that I decided to post a more general best practice solution inquiry to the community.
What I have are huge code blocks, algorithms that deal with graphs. In C they were explicitly defined for 8 data types (u/i8, u/i16, u/i32, u/i64) resulting in a big code base that latter broke the library due to multiple changes being introduced for different types. Afterwords I re-implemented the library in C++ using template programming having only one template function. That worked fine and all commits applied to all data types. Now, seeing how Rust is becoming a new C/C++ standard I wish to re-implement the libraries once again. However, in order to reduce my headbanging i ask for your help.
A really small example:
pub type A<T> = Vec<T>;
pub trait Trait<T> {
fn compute(x: T) -> A<T>;
}
impl Trait<u32> for A<u32>
{
fn compute(x:u32) -> A<u32>{
let mut v : A<u32> = Vec::new();
let mut i = x;
while i+i < x*x {
v.push(i);
i= i+1;
}
v
}
}
impl Trait<i32> for A<i32>
{
fn compute(x:i32) -> A<i32>{
let mut v : A<i32> = Vec::new();
let mut i = x;
while i+i < x*x {
v.push(i);
i= i+1;
}
v
}
}
impl Trait<u64> for A<u64>
{
fn compute(x:u64) -> A<u64>{
let mut v : A<u64> = Vec::new();
let mut i = x;
while i+i < x*x {
v.push(i);
i= i+1;
}
v
}
}
impl Trait<i64> for A<i64>
{
fn compute(x:i64) -> A<i64>{
let mut v : A<i64> = Vec::new();
let mut i = x;
while i+i < x*x {
v.push(i);
i= i+1;
}
v
}
}
fn main (){
let z = 4i32;
let u = 4u64;
let a = A::compute(z);
let b= A::compute(u);
println!("{:?},{:?}", a,b);
}
So here I would like to have only one function that accepts all 4 types. The reason I would like to stick to traits is because the underlining function can than be implemented for different, generic in design, objects and still have a proper interface (proper according to my personal view). How would one resolve this problem and still leave loops in their primitive forms as I am afraid that if i mess with them I will mess with speed, efficiency and readability (at least this was the reason I left them like that initially when i saw a proper OO wrapping affected speed and readability of the initial code). Any advice on how to reduce code base and preserve readability/execution speed, is much appreciated. Keep in mind I am still new to Rust and do not know much of the language features some of you may consider trivial, so any advice is more than welcomed .
Thank you !