match enum
enum RoughTime {
InThePast(TimeUnit, u32),
JustNow,
InTheFuture(TimeUnit, u32),
}
fn rough_time_to_string(rt: RoughTime) -> String {
match rt {
RoughTime::InThePast(units, count) =>
format!("{} {} ago", count, units.plural()),
RoughTime::JustNow => {
String::from("just now")
},
RoughTime::InTheFuture(units, count) => {
format!("{} {} from now", count, units.plural())
}
}
}
test
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_roughtime() {
let rt = RoughTime::InTheFuture(TimeUnit::Months, 10);
let res = rough_time_to_string(rt);
assert_eq!("10 months from now", res.to_string());
}
}
Option
use std::env;
fn main() {
let name = env::args().skip(1).next();
match name {
Some(n) => println!("Hi there {}", n),
None => println!("didn't receive any name")
}
}
shutcut
use std::env;
fn main() {
let name = env::args().skip(1).next().unwrap();
// let name = env::args().skip(1).next().expect("name must exists");
println!("name is {}", name);
}
if let
let color Option<&str> = None;
if let Some(c) = color {
println!("the color is {}", c);
}
while let
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop() {
println!("{}", top);
}
match guard
let num = Some(4);
match num {
Some(x) if x < 5 => println!("less than five: {}", x),
Some(x) => println!("{}", x),
None => (),
}
reference outer variable
fn main() {
let x = Some(5);
let y = 10;
match x {
Some(50) => println!("Got 50"),
Some(n) if n == y => println!("Matched, n = {:?}", n),
_ => println!("Default case, x = {:?}", x),
}
println!("at the end: x = {:?}, y = {:?}", x, y);
}
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
let x = 4;
let y = false;
match x {
4 | 5 | 6 if y => println!("yes"),
_ => println!("no"),
}
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
enum Message {
Hello { id: i32 },
}
let msg = Message::Hello { id: 5 };
match msg {
Message::Hello { id: id_variable @ 3..=7 } => { // ..= is inclusive match
println!("Found an id in range: {}", id_variable)
},
Message::Hello { id: 10...12 } => { // ... is deprecated
println!("Found an id in another range")
},
Message::Hello { id } => {
println!("Found some other id: {}", id)
},
}
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.