# Structs and impl Blocks — Rust

Source: https://www.skillbyai.com/en/rust/t-structs

> Data with methods.

## &self, &mut self, Self

A **struct** groups named fields; an `impl` block adds **methods** and associated functions. A method's receiver says how it uses the value: `&self` reads, `&mut self` modifies, `self` consumes. Associated functions without self (like `Account::new`) act as constructors. `#[derive(Debug, Clone, PartialEq)]` asks the compiler to generate common trait implementations: debug printing with `{:?}`, cloning and equality.

## Model data and behaviour precisely

Structs hold data, enums model alternatives, and traits define shared behaviour.

![Three ideas: structs and impl, enums and Option, traits and generics.](assets/figures/rust/section-4-map.svg) — Figure 4.1 — Structs, enums and traits.

## An account with a constructor and methods, run

I ran this with Rust 1.99.0 (cargo run, edition 2024, standard library only). new builds the struct, deposit takes &mut self, summary takes &self, and derived traits give debug printing, cloning and ==.

```rust
#[derive(Debug, Clone, PartialEq)]
struct Account {
    owner: String,
    balance: u64,
}

impl Account {
    fn new(owner: &str) -> Self {
        Self { owner: owner.to_string(), balance: 0 }
    }
    fn deposit(&mut self, amount: u64) {
        self.balance += amount;
    }
    fn summary(&self) -> String {
        format!("{} has {}", self.owner, self.balance)
    }
}

fn main() {
    let mut acc = Account::new("Asha");
    acc.deposit(150);
    println!("{}", acc.summary());
    println!("{acc:?}");
    let other = acc.clone();
    println!("equal: {}", acc == other);
}
```

Output:

```
Asha has 150
Account { owner: "Asha", balance: 150 }
equal: true
```

## Derive what you need

Deriving Debug on most types makes logging and debugging much easier.

**Quiz:** Which receiver lets a method modify the struct?

- [ ] static self
- [ ] &self
- [ ] Self
- [x] &mut self

*Answer:* &mut self. Mutation needs an exclusive borrow.
