title: Structs
A struct groups related data together under a single name. Think of it like a record or object with named fields.
Defining and creating a struct
struct User {
username: String,
email: String,
age: u32,
active: bool,
}
let user = User {
username: String::from("alice"),
email: String::from("alice@example.com"),
age: 30,
active: true,
};Accessing fields
println!("{}", user.username); // "alice"To mutate fields, the entire instance must be mut:
let mut user = User { ... };
user.age = 31;Struct update syntax
Create a new instance based on an existing one, overriding only some fields:
let user2 = User {
email: String::from("bob@example.com"),
..user // copy remaining fields from user
};Note: ..user moves any non-Copy fields, so user may be partially invalid after this.
Tuple structs
Structs without named fields — useful when the name alone gives enough context:
struct Point(f64, f64);
struct Color(u8, u8, u8);
let origin = Point(0.0, 0.0);
let red = Color(255, 0, 0);
println!("{}", origin.0); // access by indexMethods
Methods are functions attached to a struct, defined inside an impl block. The first parameter is always self (the instance):
struct Rectangle {
width: f64,
height: f64,
}
impl Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
fn scale(&mut self, factor: f64) {
self.width *= factor;
self.height *= factor;
}
}
let mut rect = Rectangle { width: 10.0, height: 5.0 };
println!("{}", rect.area()); // 50.0
rect.scale(2.0);
println!("{}", rect.area()); // 200.0&self— borrows the instance immutably (read only)&mut self— borrows the instance mutably (can modify fields)self— takes ownership (consumes the instance, rare)
Associated functions
Functions in impl that don’t take self are called associated functions. They’re often used as constructors:
impl Rectangle {
fn square(size: f64) -> Self {
Self { width: size, height: size }
}
}
let sq = Rectangle::square(5.0); // called with :: not .Self is shorthand for the type being implemented (Rectangle here).