]> git.proxmox.com Git - rustc.git/blame - src/doc/trpl/structs.md
Imported Upstream version 1.1.0+dfsg1
[rustc.git] / src / doc / trpl / structs.md
CommitLineData
9346a6ac
AL
1% Structs
2
bd371182 3Structs are a way of creating more complex data types. For example, if we were
9346a6ac
AL
4doing calculations involving coordinates in 2D space, we would need both an `x`
5and a `y` value:
6
7```rust
8let origin_x = 0;
9let origin_y = 0;
10```
11
12A struct lets us combine these two into a single, unified datatype:
13
14```rust
15struct Point {
16 x: i32,
17 y: i32,
18}
19
20fn main() {
21 let origin = Point { x: 0, y: 0 }; // origin: Point
22
23 println!("The origin is at ({}, {})", origin.x, origin.y);
24}
25```
26
bd371182
AL
27There’s a lot going on here, so let’s break it down. We declare a `struct` with
28the `struct` keyword, and then with a name. By convention, `struct`s begin with
29a capital letter and are camel cased: `PointInSpace`, not `Point_In_Space`.
9346a6ac
AL
30
31We can create an instance of our struct via `let`, as usual, but we use a `key:
bd371182 32value` style syntax to set each field. The order doesn’t need to be the same as
9346a6ac
AL
33in the original declaration.
34
35Finally, because fields have names, we can access the field through dot
36notation: `origin.x`.
37
38The values in structs are immutable by default, like other bindings in Rust.
39Use `mut` to make them mutable:
40
41```rust
42struct Point {
43 x: i32,
44 y: i32,
45}
46
47fn main() {
48 let mut point = Point { x: 0, y: 0 };
49
50 point.x = 5;
51
52 println!("The point is at ({}, {})", point.x, point.y);
53}
54```
55
56This will print `The point is at (5, 0)`.
57
58Rust does not support field mutability at the language level, so you cannot
59write something like this:
60
61```rust,ignore
62struct Point {
63 mut x: i32,
64 y: i32,
65}
66```
67
68Mutability is a property of the binding, not of the structure itself. If you’re
69used to field-level mutability, this may seem strange at first, but it
70significantly simplifies things. It even lets you make things mutable for a short
71time only:
72
73
74```rust,ignore
75struct Point {
76 x: i32,
77 y: i32,
78}
79
80fn main() {
81 let mut point = Point { x: 0, y: 0 };
82
83 point.x = 5;
84
85 let point = point; // this new binding can’t change now
86
87 point.y = 6; // this causes an error
88}
89```
bd371182
AL
90
91# Update syntax
92
93A `struct` can include `..` to indicate that you want to use a copy of some
94other struct for some of the values. For example:
95
96```rust
97struct Point3d {
98 x: i32,
99 y: i32,
100 z: i32,
101}
102
103let mut point = Point3d { x: 0, y: 0, z: 0 };
104point = Point3d { y: 1, .. point };
105```
106
107This gives `point` a new `y`, but keeps the old `x` and `z` values. It doesn’t
108have to be the same `struct` either, you can use this syntax when making new
109ones, and it will copy the values you don’t specify:
110
111```rust
112# struct Point3d {
113# x: i32,
114# y: i32,
115# z: i32,
116# }
117let origin = Point3d { x: 0, y: 0, z: 0 };
118let point = Point3d { z: 1, x: 2, .. origin };
119```
120
121# Tuple structs
122
123Rust has another data type that’s like a hybrid between a [tuple][tuple] and a
124struct, called a ‘tuple struct’. Tuple structs have a name, but
125their fields don’t:
126
127```rust
128struct Color(i32, i32, i32);
129struct Point(i32, i32, i32);
130```
131
132[tuple]: primitive-types.html#tuples
133
134These two will not be equal, even if they have the same values:
135
136```rust
137# struct Color(i32, i32, i32);
138# struct Point(i32, i32, i32);
139let black = Color(0, 0, 0);
140let origin = Point(0, 0, 0);
141```
142
143It is almost always better to use a struct than a tuple struct. We would write
144`Color` and `Point` like this instead:
145
146```rust
147struct Color {
148 red: i32,
149 blue: i32,
150 green: i32,
151}
152
153struct Point {
154 x: i32,
155 y: i32,
156 z: i32,
157}
158```
159
160Now, we have actual names, rather than positions. Good names are important,
161and with a struct, we have actual names.
162
163There _is_ one case when a tuple struct is very useful, though, and that’s a
164tuple struct with only one element. We call this the ‘newtype’ pattern, because
165it allows you to create a new type, distinct from that of its contained value
166and expressing its own semantic meaning:
167
168```rust
169struct Inches(i32);
170
171let length = Inches(10);
172
173let Inches(integer_length) = length;
174println!("length is {} inches", integer_length);
175```
176
177As you can see here, you can extract the inner integer type through a
178destructuring `let`, just as with regular tuples. In this case, the
179`let Inches(integer_length)` assigns `10` to `integer_length`.
180
181# Unit-like structs
182
183You can define a struct with no members at all:
184
185```rust
186struct Electron;
187```
188
189Such a struct is called ‘unit-like’ because it resembles the empty
190tuple, `()`, sometimes called ‘unit’. Like a tuple struct, it defines a
191new type.
192
193This is rarely useful on its own (although sometimes it can serve as a
194marker type), but in combination with other features, it can become
195useful. For instance, a library may ask you to create a structure that
196implements a certain [trait][trait] to handle events. If you don’t have
197any data you need to store in the structure, you can just create a
198unit-like struct.
d9579d0f
AL
199
200[trait]: traits.html