mirror of https://github.com/rust-lang/reference
143 lines
5.3 KiB
Markdown
143 lines
5.3 KiB
Markdown
# Struct expressions
|
|
|
|
> **<sup>Syntax</sup>**\
|
|
> _StructExpression_ :\
|
|
> _StructExprStruct_\
|
|
> | _StructExprTuple_\
|
|
> | _StructExprUnit_
|
|
>
|
|
> _StructExprStruct_ :\
|
|
> [_PathInExpression_] `{` (_StructExprFields_ | _StructBase_)<sup>?</sup> `}`
|
|
>
|
|
> _StructExprFields_ :\
|
|
> _StructExprField_ (`,` _StructExprField_)<sup>\*</sup> (`,` _StructBase_ | `,`<sup>?</sup>)
|
|
>
|
|
> _StructExprField_ :\
|
|
> [_OuterAttribute_] <sup>\*</sup>\
|
|
> (\
|
|
> [IDENTIFIER]\
|
|
> | ([IDENTIFIER] | [TUPLE_INDEX]) `:` [_Expression_]\
|
|
> )
|
|
>
|
|
> _StructBase_ :\
|
|
> `..` [_Expression_]
|
|
>
|
|
> _StructExprTuple_ :\
|
|
> [_PathInExpression_] `(`\
|
|
> ( [_Expression_] (`,` [_Expression_])<sup>\*</sup> `,`<sup>?</sup> )<sup>?</sup>\
|
|
> `)`
|
|
>
|
|
> _StructExprUnit_ : [_PathInExpression_]
|
|
|
|
A *struct expression* creates a struct, enum, or union value.
|
|
It consists of a path to a [struct], [enum variant], or [union] item followed by the values for the fields of the item.
|
|
There are three forms of struct expressions: struct, tuple, and unit.
|
|
|
|
The following are examples of struct expressions:
|
|
|
|
```rust
|
|
# struct Point { x: f64, y: f64 }
|
|
# struct NothingInMe { }
|
|
# struct TuplePoint(f64, f64);
|
|
# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } }
|
|
# struct Cookie; fn some_fn<T>(t: T) {}
|
|
Point {x: 10.0, y: 20.0};
|
|
NothingInMe {};
|
|
TuplePoint(10.0, 20.0);
|
|
TuplePoint { 0: 10.0, 1: 20.0 }; // Results in the same value as the above line
|
|
let u = game::User {name: "Joe", age: 35, score: 100_000};
|
|
some_fn::<Cookie>(Cookie);
|
|
```
|
|
|
|
## Field struct expression
|
|
|
|
A struct expression with fields enclosed in curly braces allows you to specify the value for each individual field in any order.
|
|
The field name is separated from its value with a colon.
|
|
|
|
A value of a [union] type can only be created using this syntax, and it must specify exactly one field.
|
|
|
|
## Functional update syntax
|
|
|
|
A struct expression that constructs a value of a struct type can terminate with the syntax `..` followed by an expression to denote a functional update.
|
|
The expression following `..` (the base) must have the same struct type as the new struct type being formed.
|
|
|
|
The entire expression uses the given values for the fields that were specified and moves or copies the remaining fields from the base expression.
|
|
As with all struct expressions, all of the fields of the struct must be [visible], even those not explicitly named.
|
|
|
|
```rust
|
|
# struct Point3d { x: i32, y: i32, z: i32 }
|
|
let mut base = Point3d {x: 1, y: 2, z: 3};
|
|
let y_ref = &mut base.y;
|
|
Point3d {y: 0, z: 10, .. base}; // OK, only base.x is accessed
|
|
drop(y_ref);
|
|
```
|
|
|
|
Struct expressions with curly braces can't be used directly in a [loop] or [if] expression's head, or in the [scrutinee] of an [if let] or [match] expression.
|
|
However, struct expressions can be used in these situations if they are within another expression, for example inside [parentheses].
|
|
|
|
The field names can be decimal integer values to specify indices for constructing tuple structs.
|
|
This can be used with base structs to fill out the remaining indices not specified:
|
|
|
|
```rust
|
|
struct Color(u8, u8, u8);
|
|
let c1 = Color(0, 0, 0); // Typical way of creating a tuple struct.
|
|
let c2 = Color{0: 255, 1: 127, 2: 0}; // Specifying fields by index.
|
|
let c3 = Color{1: 0, ..c2}; // Fill out all other fields using a base struct.
|
|
```
|
|
|
|
### Struct field init shorthand
|
|
|
|
When initializing a data structure (struct, enum, union) with named (but not numbered) fields, it is allowed to write `fieldname` as a shorthand for `fieldname: fieldname`.
|
|
This allows a compact syntax with less duplication.
|
|
For example:
|
|
|
|
```rust
|
|
# struct Point3d { x: i32, y: i32, z: i32 }
|
|
# let x = 0;
|
|
# let y_value = 0;
|
|
# let z = 0;
|
|
Point3d { x: x, y: y_value, z: z };
|
|
Point3d { x, y: y_value, z };
|
|
```
|
|
|
|
## Tuple struct expression
|
|
|
|
A struct expression with fields enclosed in parentheses constructs a tuple struct.
|
|
Though it is listed here as a specific expression for completeness, it is equivalent to a [call expression] to the tuple struct's constructor. For example:
|
|
|
|
```rust
|
|
struct Position(i32, i32, i32);
|
|
Position(0, 0, 0); // Typical way of creating a tuple struct.
|
|
let c = Position; // `c` is a function that takes 3 arguments.
|
|
let pos = c(8, 6, 7); // Creates a `Position` value.
|
|
```
|
|
|
|
## Unit struct expression
|
|
|
|
A unit struct expression is just the path to a unit struct item.
|
|
This refers to the unit struct's implicit constant of its value.
|
|
The unit struct value can also be constructed with a fieldless struct expression. For example:
|
|
|
|
```rust
|
|
struct Gamma;
|
|
let a = Gamma; // Gamma unit value.
|
|
let b = Gamma{}; // Exact same value as `a`.
|
|
```
|
|
|
|
[_OuterAttribute_]: ../attributes.md
|
|
[IDENTIFIER]: ../identifiers.md
|
|
[TUPLE_INDEX]: ../tokens.md#tuple-index
|
|
[_Expression_]: ../expressions.md
|
|
[_PathInExpression_]: ../paths.md#paths-in-expressions
|
|
[call expression]: call-expr.md
|
|
[enum variant]: ../items/enumerations.md
|
|
[if let]: if-expr.md#if-let-expressions
|
|
[if]: if-expr.md#if-expressions
|
|
[loop]: loop-expr.md
|
|
[match]: match-expr.md
|
|
[parentheses]: grouped-expr.md
|
|
[struct]: ../items/structs.md
|
|
[union]: ../items/unions.md
|
|
[visible]: ../visibility-and-privacy.md
|
|
[scrutinee]: ../glossary.md#scrutinee
|