diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md index 1abd4ca6c2174..26574f15c2c62 100644 --- a/src/doc/trpl/patterns.md +++ b/src/doc/trpl/patterns.md @@ -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, +struct Point { + x: i32, + y: i32, } -let name = "Steve".to_string(); -let mut x: Option = 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. @@ -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, } -let origin = Point { x: 0, y: 0 }; - -match origin { - Point { x, y } => println!("({},{})", x, y), +let name = "Steve".to_string(); +let mut x: Option = 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