From d047b26213070503a39f247ba530ed195c4c5434 Mon Sep 17 00:00:00 2001 From: Zykino Date: Fri, 19 Oct 2018 00:40:19 +0200 Subject: [PATCH] Finish chapter6: Enums and pattern matching --- src/main.rs | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index cfd45af..6c97586 100644 --- a/src/main.rs +++ b/src/main.rs @@ -618,7 +618,7 @@ fn defining_enum() { println!("Instead of combining an enum and a struct, we can put the datas directly into the enum: {:?}", home); println!("Doing so also permit to have differents types for each elements: {:?}", loopback); - println!("NOTE: The standard library implements an IpAddr enum, beter use it than our custom one 😉."); + println!("NOTE: The standard library implements an IpAddr enum, better use it than our custom one 😉."); impl IpAddr { fn route(&self) { @@ -644,12 +644,121 @@ fn defining_enum() { println!("We will have to take care of the `Option` enum, so checking if the value is _y: {:?} `Some` or _z: {:?} `None`.", _y, _z); println!("Instead of believing there is a value when really there is a null value."); } + + println!(); } fn match_control_flow() { - unimplemented!() + { + #[derive(Debug)] + enum UsState { + _Alabama, + Alaska, + // ... + } + + enum UsCoin { + Penny, + Nickel, + Dime, + Quarter(UsState), + } + + fn value_in_cents(coin: UsCoin) -> u32 { + match coin { + UsCoin::Penny => { + println!("Lucky penny!"); + 1 + }, + UsCoin::Nickel => 5, + UsCoin::Dime => 10, + UsCoin::Quarter(state) => { + println!("State quarter from {:?}!", state); + 25 + }, + } + } + + println!("With the match control flow we can get the value of a Penny: {:?}", value_in_cents(UsCoin::Penny)); + println!("Or any other US coin vakue of the `enum`. Nickel: {:?}", value_in_cents(UsCoin::Nickel)); + println!("The compiler will make sure we mach every value possibles values when using the `match` control flow. Dime: {:?}", value_in_cents(UsCoin::Dime)); + println!("It's like a `switch case break` where you have to make sure all options are covered."); + println!("We can even match with the value contains in the enum. Quarter: {:?}", value_in_cents(UsCoin::Quarter(UsState::Alaska))); + } + + { + fn plus_one(x: Option) -> Option { + match x { + None => None, + Some(i) => Some(i + 1), + } + } + + let five = Some(5); + let six = plus_one(five); + let none = plus_one(None); + + println!("Example use of `match` with the `Option` enum: five = {:?}, plus_one = {:?}, None plus_one = {:?}", five, six, none); + + let some_u8_value = 7u8; + match some_u8_value { + 1 => println!("one"), + 3 => println!("three"), + 5 => println!("five"), + 7 => println!("seven"), + _ => (), // `_` is a placeholder and `()` is the unit value + } + } + + println!(); } +#[allow(dead_code, unused_assignments, unused_variables)] fn concise_control_flow_if_let() { - unimplemented!() + println!("When we only want to match one element, a `match` control flow may be berbose."); + println!("Instead we can use the `if let [else]` syntax."); + + let some_u8_value = Some(0u8); + + // This is the same as ... + match some_u8_value { + Some(3) => println!("three"), + _ => (), + } + // ... this. + if let Some(3) = some_u8_value { + println!("three"); + } + + #[derive(Clone, Copy, Debug)] + enum UsState { + Alabama, + Alaska, + // ... + } + #[derive(Clone, Copy)] + enum UsCoin { + Penny, + Nickel, + Dime, + Quarter(UsState), + } + + let coin = UsCoin::Penny; + + // And this is the same as ... + let mut count = 0; + match coin { + UsCoin::Quarter(state) => println!("State quarter from {:?}!", state), + _ => count += 1, + } + // ... this. + let mut count = 0; + if let UsCoin::Quarter(state) = coin { + println!("State quarter from {:?}!", state); + } else { + count += 1; + } + + println!(); }