You are viewing a free preview of this lesson.
Subscribe to unlock all 10 lessons in this course and every other course on LearningBro.
Structs and enums are Rust's primary tools for creating custom data types. Combined with pattern matching, they form a powerful and expressive type system.
A struct groups related data together:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
let user1 = User {
username: String::from("alice"),
email: String::from("alice@example.com"),
sign_in_count: 1,
active: true,
};
When variable names match field names:
fn build_user(email: String, username: String) -> User {
User {
email, // shorthand for email: email
username, // shorthand for username: username
active: true,
sign_in_count: 1,
}
}
Create a new struct based on an existing one:
let user2 = User {
email: String::from("bob@example.com"),
..user1 // remaining fields from user1
};
Tip: The
..user1syntax moves any non-Copy fields fromuser1. After this,user1.usernameis no longer valid (it was moved), butuser1.activeanduser1.sign_in_countare still valid (they are Copy types).
Named tuples with struct semantics:
struct Colour(i32, i32, i32);
struct Point(f64, f64, f64);
let black = Colour(0, 0, 0);
let origin = Point(0.0, 0.0, 0.0);
Structs with no fields (useful for implementing traits):
struct AlwaysEqual;
Use impl blocks to add behaviour to structs:
struct Rectangle {
width: f64,
height: f64,
}
impl Rectangle {
// Method — takes &self as first parameter
fn area(&self) -> f64 {
self.width * self.height
}
// Method with mutable reference
fn scale(&mut self, factor: f64) {
self.width *= factor;
self.height *= factor;
}
// Associated function (no self) — like a static method
fn square(size: f64) -> Self {
Self {
width: size,
height: size,
}
}
}
let mut rect = Rectangle { width: 30.0, height: 50.0 };
println!("Area: {}", rect.area()); // method call
rect.scale(2.0);
let sq = Rectangle::square(10.0); // associated function call
| Receiver | Meaning |
|---|---|
&self | Immutable borrow of the instance |
&mut self | Mutable borrow of the instance |
self | Takes ownership of the instance |
No self | Associated function (called with ::) |
An enum defines a type that can be one of several variants:
enum Direction {
North,
South,
East,
West,
}
let heading = Direction::North;
Each variant can hold different types and amounts of data:
enum Message {
Quit, // no data
Move { x: i32, y: i32 }, // named fields (like a struct)
Write(String), // a single String
ChangeColour(i32, i32, i32), // three i32 values
}
let msg = Message::Write(String::from("hello"));
Subscribe to continue reading
Get full access to this lesson and all 10 lessons in this course.