Monday, June 5, 2023

Rust Generics and Traits


 


This post includes an example demonstrating usage of Generics and Traits in Rust.


use std::fmt::Display;

fn main() {
// trait is similar to interfaces in other languages
trait Hashed {
fn get_hash_key(&self) -> String;
}

// here we have a trait that also includes a default implementation
trait FirstAndLastName {
fn get_names(&self) -> (&str, &str);
fn get_names_last_before_first(&self) -> (&str, &str) {
let (name1, name2) = &self.get_names();
(name2, name1)
}
}

// this is a generic struct, it uses the 'Display' bound to make sure the the T is printable
struct SomethingWithNames<T:Display> {
something: T,
first_name: String,
last_name: String,
}

// here we create an implementation for the generic struct. the return value is the generic type
impl<T:Display> SomethingWithNames<T> {
fn get_value(&self) -> &T {
&self.something
}
}

// this is a function with generic implementation
fn print_something<T: Display>(something: SomethingWithNames<T>) {
let (name1, name2) = something.get_names();
println!("The mystery name of {} is: {}, {}\nThe hash is {}",
something.get_value(), name1, name2, something.get_hash_key());
}

// we implement the hash trait for our first struct
impl<T: Display> Hashed for SomethingWithNames<T> {
fn get_hash_key(&self) -> String {
format!("{}{}{}", &self.something, &self.first_name, &self.last_name)
}
}

// and we implement the hash trait for our second struct
impl Hashed for MyNumber {
fn get_hash_key(&self) -> String {
format!("{}", &self.n)
}
}

// we also implement the names trait for the generic struct
impl<T:Display> FirstAndLastName for SomethingWithNames<T> {
fn get_names(&self) -> (&str, &str) {
(&self.first_name, &self.last_name)
}
}

// here we create 2 different "somethings", based on different types: int and string
let the_answer = SomethingWithNames {
something: 42,
first_name: String::from("the answer"),
last_name: String::from("to everything"),
};

let john = SomethingWithNames {
something: "john",
first_name: String::from("john"),
last_name: String::from("doe"),
};

print_something(the_answer);
print_something(john);


// this is another totally different struct that gets the hash implementation
struct MyNumber {
n: i32,
}

let just_a_number = MyNumber {
n: 13,
};

println!("The hash for just a number is {}", just_a_number.get_hash_key());
}




 



No comments:

Post a Comment