# 模式

let x = 1;

match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("anything"),
}


let x = 1;
let c = 'c';

match c {
x => println!("x: {} c: {}", x, c),
}

println!("x: {}", x)


x: c c: c
x: 1


## 多重模式（Multiple patterns）

let x = 1;

match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}


## 解構（Destructuring）

struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { x, y } => println!("({},{})", x, y),
}


struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { x: x1, y: y1 } => println!("({},{})", x1, y1),
}


struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { x, .. } => println!("x is {}", x),
}


struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { y, .. } => println!("y is {}", y),
}


## 忽略綁定

# let some_value: Result<i32, &'static str> = Err("There was an error");
match some_value {
Ok(value) => println!("got a value: {}", value),
Err(_) => println!("an error occurred"),
}


_ 在任何建立綁定的模式中都有效。 這在大型結構體中要忽略某些部份時也非常有用：

fn coordinate() -> (i32, i32, i32) {
// generate and return some sort of triple tuple
# (1, 2, 3)
}

let (x, _, z) = coordinate();


let tuple: (u32, String) = (5, String::from("five"));

// Here, tuple is moved, because the String moved:
let (x, _s) = tuple;

// The next line would give "error: use of partially moved value: tuple"
// println!("Tuple is: {:?}", tuple);

// However,

let tuple = (5, String::from("five"));

// Here, tuple is _not_ moved, as the String was never moved, and u32 is Copy:
let (x, _) = tuple;

// That means this works:
println!("Tuple is: {:?}", tuple);


// Here, the String created will be dropped immediately, as it’s not bound:

let _ = String::from("  hello  ").trim();


enum OptionalTuple {
Value(i32, i32, i32),
Missing,
}

let x = OptionalTuple::Value(5, -2, 3);

match x {
OptionalTuple::Value(..) => println!("Got a tuple!"),
OptionalTuple::Missing => println!("No such luck."),
}


## ref 與 ref mut

let x = 5;

match x {
ref r => println!("Got a reference to {}", r),
}


let mut x = 5;

match x {
ref mut mr => println!("Got a mutable reference to {}", mr),
}


## 範圍

let x = 1;

match x {
1 ... 5 => println!("one through five"),
_ => println!("anything"),
}


let x = '💅';

match x {
'a' ... 'j' => println!("early letter"),
'k' ... 'z' => println!("late letter"),
_ => println!("something else"),
}


## 綁定

let x = 1;

match x {
e @ 1 ... 5 => println!("got a range element {}", e),
_ => println!("anything"),
}


#[derive(Debug)]
struct Person {
name: Option<String>,
}

let name = "Steve".to_string();
let x: Option<Person> = Some(Person { name: Some(name) });
match x {
Some(Person { name: ref a @ Some(_), .. }) => println!("{:?}", a),
_ => {}
}


let x = 5;

match x {
e @ 1 ... 5 | e @ 8 ... 10 => println!("got a range element {}", e),
_ => println!("anything"),
}


## 守衛（Guards）

enum OptionalInt {
Value(i32),
Missing,
}

let x = OptionalInt::Value(5);

match x {
OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"),
OptionalInt::Value(..) => println!("Got an int!"),
OptionalInt::Missing => println!("No such luck."),
}


let x = 4;
let y = false;

match x {
4 | 5 if y => println!("yes"),
_ => println!("no"),
}


(4 | 5) if y => ...


4 | (5 if y) => ...


## 混合與配對（Mix and Match）

match x {
Foo { x: Some(ref name), y: None } => ...
}


commit b49ce1a