Skip to content
Snippets Groups Projects
Commit ebcd5f89 authored by orestis.malaspin's avatar orestis.malaspin Committed by Michaël El Kharroubi
Browse files

Adds part03 traits and genericity

parent 2a7c5bc3
No related branches found
No related tags found
No related merge requests found
[package]
name = "part03"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
/// In part03 we introduce genericity through traits and in particular, [Copy],
/// [Clone], [std::fmt::Display] .
enum SomethingOrNothing<T> {
Nothing,
Something(T),
}
// We know the generic type T must be Displayable
impl<T: std::fmt::Display> SomethingOrNothing<T> {
// Static function
fn print(self) {
match self {
SomethingOrNothing::Nothing => println!("Nothing."),
SomethingOrNothing::Something(val) => println!("Something is: {}", val),
}
}
}
impl<T: Clone> Clone for SomethingOrNothing<T> {
fn clone(&self) -> Self {
match self {
SomethingOrNothing::Nothing => SomethingOrNothing::Nothing,
SomethingOrNothing::Something(val) => SomethingOrNothing::Something(val.clone()),
}
}
}
impl<T: Copy> Copy for SomethingOrNothing<T> {}
// If we remove Copy, we have a problem with the t in tab
// in the computation of the minimum.
trait Minimum: Copy {
fn min(self, rhs: Self) -> Self;
}
impl<T: Minimum> Minimum for SomethingOrNothing<T> {
fn min(self, rhs: Self) -> Self {
match (self, rhs) {
(SomethingOrNothing::Nothing, SomethingOrNothing::Nothing) => {
SomethingOrNothing::Nothing
}
(SomethingOrNothing::Something(lhs), SomethingOrNothing::Something(rhs)) => {
SomethingOrNothing::Something(lhs.min(rhs))
}
(SomethingOrNothing::Nothing, SomethingOrNothing::Something(rhs)) => {
SomethingOrNothing::Something(rhs)
}
(SomethingOrNothing::Something(lhs), SomethingOrNothing::Nothing) => {
SomethingOrNothing::Something(lhs)
}
}
}
}
// i32 is Copyable as a very basic type as f32, f64, etc.
// Arrays for example are not copyable.
impl Minimum for i32 {
fn min(self, rhs: Self) -> Self {
if self < rhs {
self
} else {
rhs
}
}
}
const SIZE: usize = 9;
fn read_command_line() -> [i32; SIZE] {
[10, 32, 12, 43, 52, 53, 83, 2, 9]
}
// Prints tab and returns tab.
// Tab would be destructed at the end of the function otherwise.
fn print_tab(tab: [i32; SIZE]) -> [i32; SIZE] {
for t in tab {
print!("{} ", t);
}
println!();
tab
}
fn find_min<T: Minimum>(tab: [T; SIZE]) -> ([T; SIZE], SomethingOrNothing<T>) {
let mut min = SomethingOrNothing::Nothing;
// Here is T is not Copyable tab is consumed and cannot be returned
for t in tab {
min = min.min(SomethingOrNothing::Something(t));
}
(tab, min)
}
fn main() {
let tab = read_command_line();
println!("Among the Somethings in the list:");
let tab = print_tab(tab);
// There are alternatives to access fields of tuples
let (_, min) = find_min(tab);
// The first field is not used therefore we can replace it with "_"
min.print();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment