diff --git a/src/expressions/tuple-expr.md b/src/expressions/tuple-expr.md index 0236d0553..cd1deb330 100644 --- a/src/expressions/tuple-expr.md +++ b/src/expressions/tuple-expr.md @@ -9,23 +9,28 @@ > _TupleElements_ :\ >    ( [_Expression_] `,` )+ [_Expression_]? -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_ :\ >    [_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 diff --git a/src/patterns.md b/src/patterns.md index a27489fc7..389caa173 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -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 > **Syntax**\ diff --git a/src/types/tuple.md b/src/types/tuple.md index 789d98342..3ee3e76ea 100644 --- a/src/types/tuple.md +++ b/src/types/tuple.md @@ -5,30 +5,43 @@ >       `(` `)`\ >    | `(` ( [_Type_] `,` )+ [_Type_]? `)` -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, Option)` -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