Skip to content

Rearrange sections in "Patterns" #27519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 122 additions & 122 deletions src/doc/trpl/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,79 +39,81 @@ match x {

This prints `one or two`.

# Ranges
# Destructuring

You can match a range of values with `...`:
If you have a compound data type, like a [`struct`][struct], you can destructure it
inside of a pattern:

```rust
let x = 1;

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

This prints `one through five`.

Ranges are mostly used with integers and `char`s:

```rust
let x = '💅';
let origin = Point { x: 0, y: 0 };

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

This prints `something else`.

# Bindings
[struct]: structs.html

You can bind values to names with `@`:
We can use `:` to give a value a different name.

```rust
let x = 1;
struct Point {
x: i32,
y: i32,
}

match x {
e @ 1 ... 5 => println!("got a range element {}", e),
_ => println!("anything"),
let origin = Point { x: 0, y: 0 };

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

This prints `got a range element 1`. This is useful when you want to
do a complicated match of part of a data structure:
If we only care about some of the values, we don’t have to give them all names:

```rust
#[derive(Debug)]
struct Person {
name: Option<String>,
struct Point {
x: i32,
y: i32,
}

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),
_ => {}
let origin = Point { x: 0, y: 0 };

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

This prints `Some("Steve")`: We’ve bound the inner `name` to `a`.
This prints `x is 0`.

If you use `@` with `|`, you need to make sure the name is bound in each part
of the pattern:
You can do this kind of match on any member, not just the first:

```rust
let x = 5;
struct Point {
x: i32,
y: i32,
}

match x {
e @ 1 ... 5 | e @ 8 ... 10 => println!("got a range element {}", e),
_ => println!("anything"),
let origin = Point { x: 0, y: 0 };

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

This prints `y is 0`.

This ‘destructuring’ behavior works on any compound data type, like
[tuples][tuples] or [enums][enums].

[tuples]: primitive-types.html#tuples
[enums]: enums.html

# Ignoring bindings

You can use `_` in a pattern to disregard the type and value.
Expand Down Expand Up @@ -162,154 +164,152 @@ match x {

This prints `Got a tuple!`.

# Guards
# ref and ref mut

You can introduce ‘match guards’ with `if`:
If you want to get a [reference][ref], use the `ref` keyword:

```rust
enum OptionalInt {
Value(i32),
Missing,
}

let x = OptionalInt::Value(5);
let x = 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."),
ref r => println!("Got a reference to {}", r),
}
```

This prints `Got an int!`.
This prints `Got a reference to 5`.

If you’re using `if` with multiple patterns, the `if` applies to both sides:
[ref]: references-and-borrowing.html

Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
keyword _creates_ a reference, for use in the pattern. If you need a mutable
reference, `ref mut` will work in the same way:

```rust
let x = 4;
let y = false;
let mut x = 5;

match x {
4 | 5 if y => println!("yes"),
_ => println!("no"),
ref mut mr => println!("Got a mutable reference to {}", mr),
}
```

This prints `no`, because the `if` applies to the whole of `4 | 5`, and not to
just the `5`, In other words, the the precedence of `if` behaves like this:
# Ranges

```text
(4 | 5) if y => ...
```
You can match a range of values with `...`:

not this:
```rust
let x = 1;

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

# ref and ref mut
This prints `one through five`.

If you want to get a [reference][ref], use the `ref` keyword:
Ranges are mostly used with integers and `char`s:

```rust
let x = 5;
let x = '💅';

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

This prints `Got a reference to 5`.
This prints `something else`.

[ref]: references-and-borrowing.html
# Bindings

Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
keyword _creates_ a reference, for use in the pattern. If you need a mutable
reference, `ref mut` will work in the same way:
You can bind values to names with `@`:

```rust
let mut x = 5;
let x = 1;

match x {
ref mut mr => println!("Got a mutable reference to {}", mr),
e @ 1 ... 5 => println!("got a range element {}", e),
_ => println!("anything"),
}
```

# Destructuring

If you have a compound data type, like a [`struct`][struct], you can destructure it
inside of a pattern:
This prints `got a range element 1`. This is useful when you want to
do a complicated match of part of a data structure:

```rust
struct Point {
x: i32,
y: i32,
#[derive(Debug)]
struct Person {
name: Option<String>,
}

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

match origin {
Point { x, y } => println!("({},{})", x, y),
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),
_ => {}
}
```

[struct]: structs.html
This prints `Some("Steve")`: We’ve bound the inner `name` to `a`.

We can use `:` to give a value a different name.
If you use `@` with `|`, you need to make sure the name is bound in each part
of the pattern:

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

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

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

If we only care about some of the values, we don’t have to give them all names:
# Guards

You can introduce ‘match guards’ with `if`:

```rust
struct Point {
x: i32,
y: i32,
enum OptionalInt {
Value(i32),
Missing,
}

let origin = Point { x: 0, y: 0 };
let x = OptionalInt::Value(5);

match origin {
Point { x, .. } => println!("x is {}", x),
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."),
}
```

This prints `x is 0`.
This prints `Got an int!`.

You can do this kind of match on any member, not just the first:
If you’re using `if` with multiple patterns, the `if` applies to both sides:

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

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

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

This prints `y is 0`.
This prints `no`, because the `if` applies to the whole of `4 | 5`, and not to
just the `5`, In other words, the the precedence of `if` behaves like this:

This ‘destructuring’ behavior works on any compound data type, like
[tuples][tuples] or [enums][enums].
```text
(4 | 5) if y => ...
```

[tuples]: primitive-types.html#tuples
[enums]: enums.html
not this:

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

# Mix and Match

Expand Down