Skip to content

Document vector destructuring with wildcard '..' #11877

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
Jan 29, 2014
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
51 changes: 38 additions & 13 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -2864,14 +2864,15 @@ match_pat : pat [ ".." pat ] ? [ "if" expr ] ;

A `match` expression branches on a *pattern*. The exact form of matching that
occurs depends on the pattern. Patterns consist of some combination of
literals, destructured enum constructors, structures, records and tuples, variable binding
specifications, wildcards (`..`), and placeholders (`_`). A `match` expression has a *head
expression*, which is the value to compare to the patterns. The type of the
patterns must equal the type of the head expression.
literals, destructured vectors or enum constructors, structures, records and
tuples, variable binding specifications, wildcards (`..`), and placeholders
(`_`). A `match` expression has a *head expression*, which is the value to
compare to the patterns. The type of the patterns must equal the type of the
head expression.

In a pattern whose head expression has an `enum` type, a placeholder (`_`) stands for a
*single* data field, whereas a wildcard `..` stands for *all* the fields of a particular
variant. For example:
In a pattern whose head expression has an `enum` type, a placeholder (`_`)
stands for a *single* data field, whereas a wildcard `..` stands for *all* the
fields of a particular variant. For example:

~~~~
enum List<X> { Nil, Cons(X, ~List<X>) }
Expand All @@ -2885,11 +2886,35 @@ match x {
}
~~~~

The first pattern matches lists constructed by applying `Cons` to any head value, and a
tail value of `~Nil`. The second pattern matches _any_ list constructed with `Cons`,
ignoring the values of its arguments. The difference between `_` and `..` is that the pattern
`C(_)` is only type-correct if `C` has exactly one argument, while the pattern `C(..)` is
type-correct for any enum variant `C`, regardless of how many arguments `C` has.
The first pattern matches lists constructed by applying `Cons` to any head
value, and a tail value of `~Nil`. The second pattern matches _any_ list
constructed with `Cons`, ignoring the values of its arguments. The difference
between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
exactly one argument, while the pattern `C(..)` is type-correct for any enum
variant `C`, regardless of how many arguments `C` has.

Used inside a vector pattern, `..` stands for any number of elements. This
wildcard can be used at most once for a given vector, which implies that it
cannot be used to specifically match elements that are at an unknown distance
from both ends of a vector, like `[.., 42, ..]`. If followed by a variable name,
it will bind the corresponding slice to the variable. Example:

~~~~
fn is_symmetric(list: &[uint]) -> bool {
match list {
[] | [_] => true,
[x, ..inside, y] if x == y => is_symmetric(inside),
_ => false
}
}

fn main() {
let sym = &[0, 1, 4, 2, 4, 1, 0];
let not_sym = &[0, 1, 7, 2, 4, 1, 0];
assert!(is_symmetric(sym));
assert!(!is_symmetric(not_sym));
}
~~~~

A `match` behaves differently depending on whether or not the head expression
is an [lvalue or an rvalue](#lvalues-rvalues-and-temporaries).
Expand Down Expand Up @@ -2972,7 +2997,7 @@ let z = match x { &0 => "zero", _ => "some" };
assert_eq!(y, z);
~~~~

A pattern that's just an identifier, like `Nil` in the previous answer,
A pattern that's just an identifier, like `Nil` in the previous example,
could either refer to an enum variant that's in scope, or bind a new variable.
The compiler resolves this ambiguity by forbidding variable bindings that occur
in `match` patterns from shadowing names of variants that are in scope.
Expand Down