rust-book/pattern_matching/src/main.rs

197 lines
4.2 KiB
Rust

struct Point {
x: i32,
y: i32,
}
struct XYZPoint {
x: i32,
y: i32,
z: i32,
}
enum Color {
Rgb(i32, i32, i32),
Hsv(i32, i32, i32)
}
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(Color),
}
fn match_variable_shadowing () {
let x = Some(5);
let y = 10;
match x {
Some(50) => println!("Got 50"),
// shadows the outer y, gets the value of x
Some(y) => println!("Matched, y = {:?}", y),
_ => println!("Default case, x = {:?}", x),
}
println!("at the end: x = {:?}, y = {:?}", x, y);
}
fn match_multiple () {
let x = 1;
match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}
}
fn match_range () {
let x = 5;
match x {
1 ... 5 => println!("one through five"),
_ => println!("something else"),
}
}
fn match_destructure_with_literals () {
let p = Point { x: 0, y: 7 };
match p {
Point { x, y: 0 } => println!("On the x axis at {}", x),
Point { x: 0, y } => println!("On the y axis at {}", y),
Point { x, y } => println!("On neither axis: ({}, {})", x, y),
}
}
fn match_destructure_enum () {
let msg = Message::ChangeColor(Color::Hsv(0, 160, 255));
match msg {
Message::ChangeColor(Color::Rgb(r, g, b)) => {
println!(
"Change the color to red {}, green {}, and blue {}",
r,
g,
b
)
},
Message::ChangeColor(Color::Hsv(h, s, v)) => {
println!(
"Change the color to hue {}, saturation {}, and value {}",
h,
s,
v
)
}
_ => ()
}
}
fn destructure_references() {
let points = vec![
Point { x: 0, y: 0 },
Point { x: 1, y: 5 },
Point { x: 10, y: -3 },
];
let sum_of_squares: i32 = points
.iter()
.map(|&Point { x, y }| x * x + y * y)
.sum();
}
fn match_ignore_value () {
let mut setting_value = Some(5);
let new_setting_value = Some(10);
match (setting_value, new_setting_value) {
(Some(_), Some(_)) => {
println!("Can't overwrite an existing customized value");
}
_ => {
setting_value = new_setting_value;
}
}
println!("setting is {:?}", setting_value);
}
fn match_ignore_value_parts () {
let origin = XYZPoint { x: 0, y: 0, z: 0 };
match origin {
XYZPoint { x, .. } => println!("x is {}", x),
}
}
fn match_ignore_value_parts_tuple () {
let numbers = (2, 4, 8, 16, 32);
match numbers {
(first, .., last) => {
println!("Some numbers: {}, {}", first, last);
},
}
}
fn match_guard() {
let num = Some(4);
match num {
Some(x) if x < 5 => println!("less than five: {}", x), // Has a match guard
Some(x) => println!("{}", x),
None => (),
}
}
fn match_variable_shadowing_fixed_with_match_guard() {
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);
}
fn at_match_var_bind() {
enum Message {
Hello { id: i32 },
}
let msg = Message::Hello { id: 5 };
match msg {
Message::Hello { id: id_variable @ 3...7 } => { // The @ binds the value and matches
println!("Found an id in range: {}", id_variable)
},
Message::Hello { id: 10...12 } => {
println!("Found an id in another range")
},
Message::Hello { id } => {
println!("Found some other id: {}", id)
},
}
}
fn main() {
match_variable_shadowing();
match_multiple();
match_range();
match_destructure_with_literals();
match_destructure_enum();
destructure_references();
match_ignore_value();
match_ignore_value_parts();
match_ignore_value_parts_tuple();
match_guard();
match_variable_shadowing_fixed_with_match_guard();
at_match_var_bind();
}