# Rust Patterns

Time：2021-12-1

### `if let`

`if let` allows you to combine if and let together to reduce the overhead of certain kinds of pattern matches.

``````let option = Some(12);
if let Some(x) = option {
foo(x);
} else {
bar();
}``````

### `while let`

In a similar fashion, while let can be used when you want to conditionally loop as long as a value matches a certain pattern.

``````let mut v = vec![1, 3, 5, 7, 11];
while let Some(x) = v.pop() {
println!("{}", x);
}
``````

### Compound mode

use`|`To match the composite pattern:

``````let x = 1;

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

### deconstruction

If there is a complex data type, such as struct, we can use pattern to deconstruct:

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

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

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

We use`:`To specify a different name:

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

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

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

If we only concern some of these values, we don’t have to specify all the names:

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

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

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

Print out`x is 0`

`deconstruction`Also fully applicable to`tuple`and`enums`

### Ignore binding

``````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
}

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

Similarly, we can use`..`To ignore multiple values:

``````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 and ref mut

If we need to get a reference, we can use`ref`keyword:

``````let x = 5;

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

here,`r`stay`match`The data type in is`&i32`In other words,`ref`A reference is created in using patterns. If you need a mutable reference, you can use`ref mut`

``````let mut x = 5;

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

### Ranges

We use`...`To match a range of values:

``````let x = 1;

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

### binding

We can pass`@`Bind value to a named variable:

``````let x = 1;

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

It is very useful in matching complex data structures, such as:

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

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

use`@`and`|`, you can match different parts:

``````let x = 5;

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

### Level

``````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."),
}
``````

## Why are go map and slice non thread safe?

Hello, I’m fried fish. At the gate of go language for the first time, many small partners will quickly master go in 3 days, start projects in 5 days, iterate online business in 14 days, troubleshoot and locate problems in 21 days, and take a reflection report. One of the most common primary mistakes, one […]