Select Git revision
main.rs 3.37 KiB
/* ANCHOR: all */
/*!
Part04 illustrates the concepts of **Ownership** and **Borrowing**. It also
presents the manual implementation of [Clone] and [Copy].
*/
// ANCHOR: something_or_nothing
enum SomethingOrNothing<T> {
Nothing,
Something(T),
}
impl<T> SomethingOrNothing<T> {
fn new(val: T) -> SomethingOrNothing<T> {
SomethingOrNothing::Something(val)
}
}
// ANCHOR_END: something_or_nothing
// ANCHOR: print
fn print<T: std::fmt::Display>(val: &SomethingOrNothing<T>) {
match val {
SomethingOrNothing::Nothing => println!("Nothing."),
SomethingOrNothing::Something(val) => println!("Something is: {}", val),
}
}
// ANCHOR_END: print
// Manual implementation of [Clone]
impl<T: Clone> Clone for SomethingOrNothing<T> {
fn clone(&self) -> Self {
match self {
SomethingOrNothing::Nothing => SomethingOrNothing::Nothing,
SomethingOrNothing::Something(val) => SomethingOrNothing::Something(val.clone()),
}
}
}
// Manual implementation of [Copy]
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.
// ANCHOR: minimum
trait Minimum: Copy {
fn min(self, rhs: Self) -> Self;
}
// ANCHOR_END: minimum
// ANCHOR: minimum_impl
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)
}
}
}
}
// ANCHOR_END: minimum_impl
impl Minimum for i32 {
fn min(self, rhs: Self) -> Self {
if self < rhs {
self
} else {
rhs
}
}
}
const SIZE: usize = 9;
// Poorly emulates the parsing of a command line.
fn read_command_line() -> [i32; SIZE] {
[10, 32, 12, 43, 52, 53, 83, 2, 9]
}
// Prints all the elements of the `tab`.
// Tab is borrowed here
// ANCHOR: print_tab
fn print_tab<T: std::fmt::Display>(tab: &[T; SIZE]) {
for t in tab {
print!("{} ", t);
}
println!();
}
// ANCHOR_END: print_tab
// Computes the minimum of a borrowed Array of a type T which implements the [Minimum] trait.
// Returns a [SomethingOrNothing::Something] containing the the minimum value
// or [SomethingOrNothing::Nothing] if no minimum value was found.
// ANCHOR: find_min
fn find_min<T: Minimum>(tab: &[T; SIZE]) -> SomethingOrNothing<T> {
let mut current_minimum = SomethingOrNothing::Nothing;
// Here is T is not Copyable tab is consumed and cannot be returned
for t in tab {
current_minimum = current_minimum.min(SomethingOrNothing::new(*t));
}
current_minimum
}
// ANCHOR_END: find_min
// ANCHOR: main
fn main() {
let tab = read_command_line();
println!("Among the Somethings in the list:");
print_tab(&tab);
let min = find_min(&tab);
print(&min);
}
// ANCHOR_END: main
/* ANCHOR_END: all */