Defining Structs
Structs let you group related data together under one name, kind of like a blueprint. Instead of passing around five separate variables for a user, you just pass one User struct. Clean, organized, and readable.
struct User {
name: String,
email: String,
active: bool,
sign_in_count: u64,
}
fn main() {
let user = User {
name: String::from("Alice"),
email: String::from("alice@example.com"),
active: true,
sign_in_count: 1,
};
println!("User: {} is active: {}", user.name, user.active);
}
Try it Yourself ->
Field Init Shorthand
When a variable name matches the field name, you can skip the colon and just write the variable name. It's a small thing, but it makes the code less noisy.
struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let name = String::from("Bob");
let email = String::from("bob@example.com");
let user = User {
name, // shorthand for name: name
email, // shorthand for email: email
active: true,
};
println!("{}", user.name);
}
Try it Yourself ->
Struct Update Syntax
Want to create a new struct that's almost like an existing one, but with a few fields changed? Use the ..other syntax. It copies the remaining fields from the other struct.
struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let user1 = User {
name: String::from("Charlie"),
email: String::from("charlie@example.com"),
active: true,
};
let user2 = User {
name: String::from("Dave"),
..user1 // copies email and active from user1
};
println!("{}", user2.email);
}
Try it Yourself ->
Tuple Structs and Unit Structs
You can create tuple structs with unnamed fields and unit structs with no fields at all. Tuple structs are great when you want a new type with a clear purpose, and unit structs are useful for implementing traits on an empty type.
struct Color(u8, u8, u8);
struct Point(f64, f64);
struct AlwaysEqual;
fn main() {
let red = Color(255, 0, 0);
let origin = Point(0.0, 0.0);
let _unit = AlwaysEqual;
println!("Color: {}, {}, {}", red.0, red.1, red.2);
}
Try it Yourself ->