Skip to content

Commit 5e296d2

Browse files
authored
Merge pull request #419 from ehuss/patterns_basic
Patterns chapter
2 parents 221ea65 + 7edf953 commit 5e296d2

10 files changed

+725
-134
lines changed

src/SUMMARY.md

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
- [Match expressions](expressions/match-expr.md)
6464
- [Return expressions](expressions/return-expr.md)
6565

66+
- [Patterns](patterns.md)
67+
6668
- [Type system](type-system.md)
6769
- [Types](types.md)
6870
- [Dynamically Sized Types](dynamically-sized-types.md)

src/expressions/closure-expr.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
A _closure expression_ defines a closure and denotes it as a value, in a single
1010
expression. A closure expression is a pipe-symbol-delimited (`|`) list of
11-
patterns followed by an expression. Type annotations may optionally be added
11+
irrefutable [patterns] followed by an expression. Type annotations may optionally be added
1212
for the type of the parameters or for the return type. If there is a return
1313
type, the expression used for the body of the closure must be a normal
1414
[block]. A closure expression also may begin with the
@@ -63,6 +63,7 @@ ten_times(move |j| println!("{}, {}", word, j));
6363

6464
[block]: expressions/block-expr.html
6565
[function definitions]: items/functions.html
66+
[patterns]: patterns.html
6667

6768
[_Expression_]: expressions.html
6869
[_BlockExpression_]: expressions/block-expr.html

src/expressions/if-expr.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ assert_eq!(y, "Bigger");
4444

4545
> **<sup>Syntax</sup>**\
4646
> _IfLetExpression_ :\
47-
> &nbsp;&nbsp; `if` `let` _Pattern_ `=` [_Expression_]<sub>_except struct expression_</sub>
47+
> &nbsp;&nbsp; `if` `let` [_Pattern_] `=` [_Expression_]<sub>_except struct expression_</sub>
4848
> [_BlockExpression_]\
4949
> &nbsp;&nbsp; (`else` (
5050
> [_BlockExpression_]
@@ -113,3 +113,4 @@ match EXPR {
113113

114114
[_Expression_]: expressions.html
115115
[_BlockExpression_]: expressions/block-expr.html
116+
[_Pattern_]: patterns.html

src/expressions/loop-expr.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ while i < 10 {
6767

6868
> **<sup>Syntax</sup>**\
6969
> [_PredicatePatternLoopExpression_] :\
70-
> &nbsp;&nbsp; `while` `let` _Pattern_ `=` [_Expression_]<sub>except struct expression</sub>
70+
> &nbsp;&nbsp; `while` `let` [_Pattern_] `=` [_Expression_]<sub>except struct expression</sub>
7171
> [_BlockExpression_]
7272
7373
A `while let` loop is semantically similar to a `while` loop but in place of a
@@ -109,7 +109,7 @@ is equivalent to
109109

110110
> **<sup>Syntax</sup>**\
111111
> _IteratorLoopExpression_ :\
112-
> &nbsp;&nbsp; `for` _Pattern_ `in` [_Expression_]<sub>except struct expression</sub>
112+
> &nbsp;&nbsp; `for` [_Pattern_] `in` [_Expression_]<sub>except struct expression</sub>
113113
> [_BlockExpression_]
114114
115115
A `for` expression is a syntactic construct for looping over elements provided
@@ -271,5 +271,6 @@ expression `()`.
271271

272272
[_Expression_]: expressions.html
273273
[_BlockExpression_]: expressions/block-expr.html
274+
[_Pattern_]: patterns.html
274275

275276
[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels

src/expressions/match-expr.md

+21-95
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,15 @@
1818
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> _MatchArmPatterns_ _MatchArmGuard_<sup>?</sup>
1919
>
2020
> _MatchArmPatterns_ :\
21-
> &nbsp;&nbsp; `|`<sup>?</sup> _Pattern_ ( `|` _Pattern_ )<sup>\*</sup>
21+
> &nbsp;&nbsp; `|`<sup>?</sup> [_Pattern_] ( `|` [_Pattern_] )<sup>\*</sup>
2222
>
2323
> _MatchArmGuard_ :\
2424
> &nbsp;&nbsp; `if` [_Expression_]
2525
2626
A *`match` expression* branches on a pattern. The exact form of matching that
27-
occurs depends on the pattern. *Patterns* consist of some combination of
28-
literals, destructured arrays or enum constructors, structs and tuples,
29-
variable binding specifications, wildcards (`..`), and placeholders (`_`). A
30-
`match` expression has a *head expression*, which is the value to compare to
31-
the patterns. The type of the patterns must equal the type of the head
32-
expression.
27+
occurs depends on the [pattern]. A `match`
28+
expression has a *head expression*, which is the value to compare to the
29+
patterns. The head expression and the patterns must have the same type.
3330

3431
A `match` behaves differently depending on whether or not the head expression
3532
is a [place expression or value expression][place expression].
@@ -62,65 +59,10 @@ match x {
6259
}
6360
```
6461

65-
Patterns that bind variables default to binding to a copy or move of the
66-
matched value (depending on the matched value's type). This can be changed to
67-
bind to a reference by using the `ref` keyword, or to a mutable reference using
68-
`ref mut`.
62+
Variables bound within the pattern are scoped to the match guard and the arm's
63+
expression. The [binding mode] (move, copy, or reference) depends on the pattern.
6964

70-
Patterns can be used to *destructure* structs, enums, and tuples. Destructuring
71-
breaks a value up into its component pieces. The syntax used is the same as
72-
when creating such values. When destructing a data structure with named (but
73-
not numbered) fields, it is allowed to write `fieldname` as a shorthand for
74-
`fieldname: fieldname`. In a pattern whose head expression has a `struct`,
75-
`enum` or `tupl` type, a placeholder (`_`) stands for a *single* data field,
76-
whereas a wildcard `..` stands for *all* the fields of a particular variant.
77-
78-
```rust
79-
# enum Message {
80-
# Quit,
81-
# WriteString(String),
82-
# Move { x: i32, y: i32 },
83-
# ChangeColor(u8, u8, u8),
84-
# }
85-
# let message = Message::Quit;
86-
match message {
87-
Message::Quit => println!("Quit"),
88-
Message::WriteString(write) => println!("{}", &write),
89-
Message::Move{ x, y: 0 } => println!("move {} horizontally", x),
90-
Message::Move{ .. } => println!("other move"),
91-
Message::ChangeColor { 0: red, 1: green, 2: _ } => {
92-
println!("color change, red: {}, green: {}", red, green);
93-
}
94-
};
95-
```
96-
97-
Patterns can also dereference pointers by using the `&`, `&mut` and `box`
98-
symbols, as appropriate. For example, these two matches on `x: &i32` are
99-
equivalent:
100-
101-
```rust
102-
let int_reference = &3;
103-
104-
let a = match *int_reference { 0 => "zero", _ => "some" };
105-
let b = match int_reference { &0 => "zero", _ => "some" };
106-
107-
assert_eq!(a, b);
108-
```
109-
110-
Subpatterns can also be bound to variables by the use of the syntax `variable @
111-
subpattern`. For example:
112-
113-
```rust
114-
let x = 1;
115-
116-
match x {
117-
e @ 1 ... 5 => println!("got a range element {}", e),
118-
_ => println!("anything"),
119-
}
120-
```
121-
122-
Multiple match patterns may be joined with the `|` operator. An inclusive range
123-
of values may be specified with `..=`. For example:
65+
Multiple match patterns may be joined with the `|` operator:
12466

12567
```rust
12668
# let x = 9;
@@ -133,34 +75,11 @@ let message = match x {
13375
assert_eq!(message, "a few");
13476
```
13577

136-
Other forms of [range] \(e.g `..` for an exclusive range, or any range with one or
137-
both endpoints left unspecified) are not supported in matches. The
138-
syntax `...` is also accepted for inclusive ranges in patterns only, for
139-
backwards compatibility.
140-
141-
Range patterns only work with [`char`] and [numeric types]. A range pattern may
142-
not be a sub-range of another range pattern inside the same `match`.
143-
144-
Slice patterns can match both arrays of fixed size and slices of dynamic size.
145-
```rust
146-
// Fixed size
147-
let arr = [1, 2, 3];
148-
match arr {
149-
[1, _, _] => "starts with one",
150-
[a, b, c] => "starts with something else",
151-
};
152-
```
153-
```rust
154-
// Dynamic size
155-
let v = vec![1, 2, 3];
156-
match v[..] {
157-
[a, b] => { /* this arm will not apply because the length doesn't match */ }
158-
[a, b, c] => { /* this arm will apply */ }
159-
_ => { /* this wildcard is required, since we don't know length statically */ }
160-
}
161-
```
78+
Please notice that the `2..=9` is a [Range Pattern], not a [Range Expression]
79+
and, thus, only those types of ranges supported by range patterns can be used
80+
in match arms.
16281

163-
Finally, match arms can accept *pattern guards* to further refine the
82+
Match arms can accept _match guards_ to further refine the
16483
criteria for matching a case. Pattern guards appear after the pattern and
16584
consist of a bool-typed expression following the `if` keyword. A pattern guard
16685
may refer to the variables bound within the pattern they follow.
@@ -205,10 +124,17 @@ meaning on match arms are [`cfg`], `cold`, and the [lint check attributes].
205124
[_BlockExpression_]: expressions/block-expr.html#block-expressions
206125
[place expression]: expressions.html#place-expressions-and-value-expressions
207126
[value expression]: expressions.html#place-expressions-and-value-expressions
208-
[`char`]: types.html#textual-types
209-
[numeric types]: types.html#numeric-types
210127
[_InnerAttribute_]: attributes.html
211128
[_OuterAttribute_]: attributes.html
212129
[`cfg`]: conditional-compilation.html
213130
[lint check attributes]: attributes.html#lint-check-attributes
214-
[range]: expressions/range-expr.html
131+
[Range Expression]: expressions/range-expr.html
132+
133+
[_Pattern_]: patterns.html
134+
[pattern]: patterns.html
135+
[Identifier Patterns]: patterns.html#identifier-patterns
136+
[Struct Patterns]: patterns.html#struct-patterns
137+
[Tuple Struct Patterns]: patterns.html#tuplestruct-patterns
138+
[Tuple Patterns]: patterns.html#tuple-patterns
139+
[Range Pattern]: patterns.html#range-patterns
140+
[binding mode]: patterns.html#binding-modes

src/items/functions.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn answer_to_life_the_universe_and_everything() -> i32 {
1818
}
1919
```
2020

21-
As with `let` bindings, function arguments are irrefutable patterns, so any
21+
As with `let` bindings, function arguments are irrefutable [patterns], so any
2222
pattern that is valid in a let binding is also valid as an argument:
2323

2424
```rust
@@ -120,7 +120,7 @@ implemented by executing an illegal instruction.
120120
[Outer attributes][attributes] are allowed on functions. [Inner
121121
attributes][attributes] are allowed directly after the `{` inside its [block].
122122

123-
This example shows an inner attribute on a function. The function will only be
123+
This example shows an inner attribute on a function. The function will only be
124124
available while running tests.
125125

126126
```
@@ -153,4 +153,5 @@ attributes].
153153
[the optimization hint attributes]: attributes.html#optimization-hints
154154
[`deprecated`]: attributes.html#deprecation
155155
[`doc`]: attributes.html#documentation
156-
[`must_use`]: attributes.html#must_use
156+
[`must_use`]: attributes.html#must_use
157+
[patterns]: patterns.html

src/macros-by-example.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ syntax named by _designator_. Valid designators are:
3636
[item]: items.html
3737
[block]: expressions/block-expr.html
3838
[statement]: statements.html
39-
[pattern]: expressions/match-expr.html
39+
[pattern]: patterns.html
4040
[expression]: expressions.html
4141
[type]: types.html
4242
[identifier]: identifiers.html

0 commit comments

Comments
 (0)