Module 3 • Lesson 15

Defining Structs

📚 8 min read 💻 Free Course 🦀 nixus.pro

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

  1. Create a Rectangle struct with width and height. Add area(), perimeter(), is_square() methods
  2. Create a BankAccount struct with balance: f64, owner: String. Add deposit(), withdraw() returning Result
  3. Use struct update syntax to create a "modified copy" of a struct

🎉 Key Takeaways