Defining Structs
#[derive(Debug, Clone)]
struct User {
username: String,
email: String,
age: u32,
active: bool,
}
fn new_user(name: &str, email: &str) -> User {
User {
username: name.to_string(),
email: email.to_string(), // Field init shorthand when names match
age: 0,
active: true,
}
}
fn main() {
let mut alice = new_user("alice", "alice@example.com");
alice.age = 30;
println!("{:?}", alice);
// Struct update syntax
let bob = User {
username: String::from("bob"),
email: String::from("bob@example.com"),
..alice // Copy remaining fields from alice
};
println!("{:?}", bob);
// Tuple struct
struct Color(u8, u8, u8);
let red = Color(255, 0, 0);
println!("Red: {}", red.0);
// Unit struct (useful with traits)
struct Marker;
let _m = Marker;
}Derived Traits
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
struct Vec2 {
x: f64,
y: f64,
}
impl Vec2 {
fn new(x: f64, y: f64) -> Self { Vec2 { x, y } }
fn zero() -> Self { Vec2::new(0.0, 0.0) }
fn length(&self) -> f64 { (self.x*self.x + self.y*self.y).sqrt() }
fn dot(&self, other: &Vec2) -> f64 { self.x*other.x + self.y*other.y }
}
fn main() {
let a = Vec2::new(3.0, 4.0);
let b = a; // Copy - both valid (because Copy is derived)
println!("length: {:.2}", a.length()); // 5.0
println!("dot: {}", a.dot(&b)); // 25.0
println!("equal: {}", a == b); // true
println!("{:?}", a);
}🎯 Practice
- Create a Rectangle struct with width and height. Add area(), perimeter(), is_square() methods
- Create a BankAccount struct with balance: f64, owner: String. Add deposit(), withdraw() returning Result
- Use struct update syntax to create a "modified copy" of a struct
🎉 Key Takeaways
- Structs group related data; use field init shorthand when variable names match fields
- Struct update syntax (..other) copies remaining fields
- #[derive(Debug)] enables {:?} printing; add Clone, Copy, PartialEq as needed
- Tuple structs (Name(T1, T2)) are named tuples; unit structs have no data