Merge pull request #899 from Havvy/tuple

Referencify tuples
This commit is contained in:
Eric Huss 2020-11-11 19:13:21 -08:00 committed by GitHub
commit a7de763c21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 45 deletions

View File

@ -9,23 +9,28 @@
> _TupleElements_ :\
> &nbsp;&nbsp; ( [_Expression_] `,` )<sup>+</sup> [_Expression_]<sup>?</sup>
Tuples are written by enclosing zero or more comma-separated expressions in
parentheses. They are used to create [tuple-typed](../types/tuple.md)
values.
Tuple expressions evaluate into [tuple values][tuple type] with the operands
initializing the elements of the tuple.
```rust
(0.0, 4.5);
("a", 4usize, true);
();
```
Tuple expressions are written by listing the [operands] in a parenthesized,
comma-separated list. 1-ary tuple expressions require a comma after their
operand to be disambiguated with a [parenthetical expression].
You can disambiguate a single-element tuple from a value in parentheses with a
comma:
The number of operands is the arity of the constructed tuple. Tuple expressions
without operands produce the unit tuple. For other tuple expressions, the first
written operand initializes the 0th element and subsequent operands initializes
the next highest element. For example, in the tuple expression
`('a', 'b', 'c')`, `'a'` initializes the value of the 0th element, `'b'` the
1st, and `'c'` the 2nd.
```rust
(0,); // single-element tuple
(0); // zero in parentheses
```
Examples of tuple expressions:
| Expression | Type |
| -------------------- | ------------ |
| `()` | `()` (unit) |
| `(0.0, 4.5)` | `(f64, f64)` |
| `("x".to_string(), )` | `(String, )` |
| `("a", 4usize, true)`| `(&'static str, usize, bool)` |
### Tuple expression attributes
@ -39,23 +44,40 @@ expressions].
> _TupleIndexingExpression_ :\
> &nbsp;&nbsp; [_Expression_] `.` [TUPLE_INDEX]
[Tuples](../types/tuple.md) and [struct tuples](../items/structs.md) can be
indexed using the number corresponding to the position of the field. The index
must be written as a [decimal literal](../tokens.md#integer-literals) with no
underscores or suffix. Tuple indexing expressions also differ from field
expressions in that they can unambiguously be called as a function. In all
other aspects they have the same behavior.
Tuple indexing expressions evaluate like [field access expressions], but access
elements of [tuples][tuple type] or [tuple structs].
Tuple index expressions are written as an operand, `.`, and a tuple index. The
index must be written as a [decimal literal] with no leading zeros, underscores,
or suffix. The operand must have the type of a tuple or tuple struct. If the
tuple index is not an element of the tuple or tuple struct, it is a compiler
error.
Examples of tuple indexing expressions:
```rust
# struct Point(f32, f32);
let pair = (1, 2);
let pair = ("a string", 2);
assert_eq!(pair.1, 2);
let unit_x = Point(1.0, 0.0);
assert_eq!(unit_x.0, 1.0);
# struct Point(f32, f32);
let point = Point(1.0, 0.0);
assert_eq!(point.0, 1.0);
assert_eq!(point.1, 0.0);
```
[Inner attributes]: ../attributes.md
[TUPLE_INDEX]: ../tokens.md#tuple-index
> **Note**: Unlike field access expressions, tuple index expressions can be the
> function operand of a [call expression] as it cannot be confused with a
> method call since method names cannot be numbers.
[_Expression_]: ../expressions.md
[_InnerAttribute_]: ../attributes.md
[attributes on block expressions]: block-expr.md#attributes-on-block-expressions
[call expression]: ./call-expr.md
[decimal literal]: ../tokens.md#integer-literals
[field access expressions]: ./field-expr.html#field-access-expressions
[Inner attributes]: ../attributes.md
[operands]: ../expressions.md
[parenthetical expression]: grouped-expr.md
[tuple type]: ../types/tuple.md
[tuple structs]: ../types/struct.md
[TUPLE_INDEX]: ../tokens.md#tuple-index

View File

@ -668,6 +668,16 @@ require a comma, and matches a tuple of any size.
The tuple pattern is refutable when one of its subpatterns is refutable.
An example of using tuple patterns:
```rust
let pair = (10, "ten");
let (a, b) = pair;
assert_eq!(a, 10);
assert_eq!(b, "ten");
```
## Grouped patterns
> **<sup>Syntax</sup>**\

View File

@ -5,30 +5,43 @@
> &nbsp;&nbsp; &nbsp;&nbsp; `(` `)`\
> &nbsp;&nbsp; | `(` ( [_Type_] `,` )<sup>+</sup> [_Type_]<sup>?</sup> `)`
A tuple *type* is a heterogeneous product of other types, called the *elements*
of the tuple. It has no nominal name and is instead structurally typed.
The *tuple type* is a structural type[^1] for heterogeneous lists of other
types. Each entry in the list is an *element*[^2] of the tuple. The position of
the element makes it the *nth element* using zero (`0`) as the initial index.
Tuple types and values are denoted by listing the types or values of their
elements, respectively, in a parenthesized, comma-separated list.
The number of elements determines the arity of the tuple. A tuple with `n`
elements is called an `n-ary tuple`. For example, a tuple with 2 elements is a
2-ary tuple.
Because tuple elements don't have a name, they can only be accessed by
pattern-matching or by using `N` directly as a field to access the `N`th
element.
For convenience and historical reasons, the tuple type with no elements (`()`)
is often called *unit* or *the unit type*. It's one value is also called *unit*
or *the unit value*.
An example of a tuple type and its use:
Tuple types are written by listing the types of their elements in a
parenthesized, comma-separated list. 1-ary tuples require a comma after their
element type to be disambiguated with a [parenthesized type].
```rust
type Pair<'a> = (i32, &'a str);
let p: Pair<'static> = (10, "ten");
let (a, b) = p;
Some examples of tuple types:
assert_eq!(a, 10);
assert_eq!(b, "ten");
assert_eq!(p.0, 10);
assert_eq!(p.1, "ten");
```
* `()` (unit)
* `(f64, f64)`
* `(String, i32)`
* `(i32, String)` (different type from the previous example)
* `(i32, f64, Vec<String>, Option<bool>)`
For historical reasons and convenience, the tuple type with no elements (`()`)
is often called unit or the unit type.
Values of this type are constructed using a [tuple expression]. Furthermore,
various expressions will produce the unit value if there is no other meaningful
value for it to evaluate to. Tuple elements can be accessed by either a [tuple
index expression] or [pattern matching].
[^1]: Structural types are always equivalent if their internal types are
equivalent. For a nominal version of tuples, see [tuple structs].
[^2]: Element is equivalent to field, except numerical indexes instead of
identifiers
[_Type_]: ../types.md#type-expressions
[parenthesized type]: ../types.md#parenthesized-types
[pattern matching]: ../patterns.md#tuple-patterns
[tuple expression]: ../expressions/tuple-expr.md#tuple-expressions
[tuple index expression]: ../expressions/tuple-expr.md#tuple-indexing-expressions
[tuple structs]: ./struct.md