2015-04-07 21:16:02 -05:00
|
|
|
|
% Structs
|
|
|
|
|
|
2015-04-10 09:37:29 -05:00
|
|
|
|
Structs are a way of creating more complex datatypes. For example, if we were
|
|
|
|
|
doing calculations involving coordinates in 2D space, we would need both an `x`
|
|
|
|
|
and a `y` value:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
let origin_x = 0;
|
|
|
|
|
let origin_y = 0;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
A struct lets us combine these two into a single, unified datatype:
|
2015-04-07 21:16:02 -05:00
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
struct Point {
|
|
|
|
|
x: i32,
|
|
|
|
|
y: i32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let origin = Point { x: 0, y: 0 }; // origin: Point
|
|
|
|
|
|
|
|
|
|
println!("The origin is at ({}, {})", origin.x, origin.y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2015-04-10 09:37:29 -05:00
|
|
|
|
There’s a lot going on here, so let’s break it down. We declare a struct with
|
2015-04-07 21:16:02 -05:00
|
|
|
|
the `struct` keyword, and then with a name. By convention, structs begin with a
|
|
|
|
|
capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
|
|
|
|
|
|
|
|
|
|
We can create an instance of our struct via `let`, as usual, but we use a `key:
|
|
|
|
|
value` style syntax to set each field. The order doesn't need to be the same as
|
|
|
|
|
in the original declaration.
|
|
|
|
|
|
|
|
|
|
Finally, because fields have names, we can access the field through dot
|
|
|
|
|
notation: `origin.x`.
|
|
|
|
|
|
|
|
|
|
The values in structs are immutable by default, like other bindings in Rust.
|
|
|
|
|
Use `mut` to make them mutable:
|
|
|
|
|
|
2015-04-10 09:37:29 -05:00
|
|
|
|
```rust
|
2015-04-07 21:16:02 -05:00
|
|
|
|
struct Point {
|
|
|
|
|
x: i32,
|
|
|
|
|
y: i32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let mut point = Point { x: 0, y: 0 };
|
|
|
|
|
|
|
|
|
|
point.x = 5;
|
|
|
|
|
|
|
|
|
|
println!("The point is at ({}, {})", point.x, point.y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This will print `The point is at (5, 0)`.
|
2015-04-10 09:37:29 -05:00
|
|
|
|
|
2015-04-14 12:41:31 -05:00
|
|
|
|
Rust does not support field mutability at the language level, so you cannot
|
|
|
|
|
write something like this:
|
2015-04-10 09:37:29 -05:00
|
|
|
|
|
|
|
|
|
```rust,ignore
|
|
|
|
|
struct Point {
|
|
|
|
|
mut x: i32,
|
|
|
|
|
y: i32,
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Mutability is a property of the binding, not of the structure itself. If you’re
|
|
|
|
|
used to field-level mutability, this may seem strange at first, but it
|
|
|
|
|
significantly simplifies things. It even lets you make things mutable for a short
|
|
|
|
|
time only:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```rust,ignore
|
|
|
|
|
struct Point {
|
|
|
|
|
x: i32,
|
|
|
|
|
y: i32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let mut point = Point { x: 0, y: 0 };
|
|
|
|
|
|
|
|
|
|
point.x = 5;
|
|
|
|
|
|
2015-04-14 12:41:31 -05:00
|
|
|
|
let point = point; // this new binding can’t change now
|
2015-04-10 09:37:29 -05:00
|
|
|
|
|
2015-04-14 12:41:31 -05:00
|
|
|
|
point.y = 6; // this causes an error
|
2015-04-10 09:37:29 -05:00
|
|
|
|
}
|
|
|
|
|
```
|