Skip to content
Snippets Groups Projects
Commit cd91b40e authored by Michaël El Kharroubi's avatar Michaël El Kharroubi :satellite:
Browse files

Merge branch 'part03' into 'main'

Adds part03 traits and genericity

See merge request orestis.malaspin/rust-101!9
parents 2a7c5bc3 ebcd5f89
Branches
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