match enum

  1. enum RoughTime {
  2. InThePast(TimeUnit, u32),
  3. JustNow,
  4. InTheFuture(TimeUnit, u32),
  5. }
  1. fn rough_time_to_string(rt: RoughTime) -> String {
  2. match rt {
  3. RoughTime::InThePast(units, count) =>
  4. format!("{} {} ago", count, units.plural()),
  5. RoughTime::JustNow => {
  6. String::from("just now")
  7. },
  8. RoughTime::InTheFuture(units, count) => {
  9. format!("{} {} from now", count, units.plural())
  10. }
  11. }
  12. }

test

  1. #[cfg(test)]
  2. mod tests {
  3. use super::*;
  4. #[test]
  5. fn test_roughtime() {
  6. let rt = RoughTime::InTheFuture(TimeUnit::Months, 10);
  7. let res = rough_time_to_string(rt);
  8. assert_eq!("10 months from now", res.to_string());
  9. }
  10. }

Option

  1. use std::env;
  2. fn main() {
  3. let name = env::args().skip(1).next();
  4. match name {
  5. Some(n) => println!("Hi there {}", n),
  6. None => println!("didn't receive any name")
  7. }
  8. }

shutcut

  1. use std::env;
  2. fn main() {
  3. let name = env::args().skip(1).next().unwrap();
  4. // let name = env::args().skip(1).next().expect("name must exists");
  5. println!("name is {}", name);
  6. }

if let

  1. let color Option<&str> = None;
  2. if let Some(c) = color {
  3. println!("the color is {}", c);
  4. }

while let

  1. let mut stack = Vec::new();
  2. stack.push(1);
  3. stack.push(2);
  4. stack.push(3);
  5. while let Some(top) = stack.pop() {
  6. println!("{}", top);
  7. }

match guard

  1. let num = Some(4);
  2. match num {
  3. Some(x) if x < 5 => println!("less than five: {}", x),
  4. Some(x) => println!("{}", x),
  5. None => (),
  6. }

reference outer variable

  1. fn main() {
  2. let x = Some(5);
  3. let y = 10;
  4. match x {
  5. Some(50) => println!("Got 50"),
  6. Some(n) if n == y => println!("Matched, n = {:?}", n),
  7. _ => println!("Default case, x = {:?}", x),
  8. }
  9. println!("at the end: x = {:?}, y = {:?}", x, y);
  10. }

here in the second arm, if n == y doesn’t intruduce new variable, that is said, we can refer outer variable in if condition

logic or

  1. let x = 4;
  2. let y = false;
  3. match x {
  4. 4 | 5 | 6 if y => println!("yes"),
  5. _ => println!("no"),
  6. }

only if x is equal to 4,5 or 6 and y is equal to true, it will print yes, otherwise it print no

@ binding

  1. enum Message {
  2. Hello { id: i32 },
  3. }
  4. let msg = Message::Hello { id: 5 };
  5. match msg {
  6. Message::Hello { id: id_variable @ 3..=7 } => { // ..= is inclusive match
  7. println!("Found an id in range: {}", id_variable)
  8. },
  9. Message::Hello { id: 10...12 } => { // ... is deprecated
  10. println!("Found an id in another range")
  11. },
  12. Message::Hello { id } => {
  13. println!("Found some other id: {}", id)
  14. },
  15. }

we’re capturing whatever value matched the range while also testing that the value matched the range pattern. if we want to know what we have capture we can use binding, in second arm, we can only tell id is in 10…12, but we can not capture what value is id. Using @ lets us test a value and save it in a variable within one pattern.