M Logo
๐Ÿ“ Rust for Beginners ยท Part 11 of 22

Rust Methods and impl Explained: &self, &mut self, Associated Functions

November 10, 2026

Welcome to episode 11 of Rust for Beginners, a series for complete beginners (no programming experience needed). In the last video, we built our own types with structs. Today, we'll give them behaviour, with methods and impl. Every code block below is the exact code from the video, ready to copy.

1. New project

Let's create a new project called rectangles, and open it in VS Code.

bash
cargo new rectangles
cd rectangles

2. impl

Here's a Rectangle with a width and a height. Methods go inside an impl block, short for implementation.

src/main.rs:

rust
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect = Rectangle { width: 30, height: 50 };
    println!("Area: {}", rect.area());
}

Output: Area: 1500

3. self

A method's first parameter is self: the rectangle it's called on. Ampersand self means it only borrows it, to read.

4. Call

We call a method with a dot: rect dot area.

5. Run A

Let's run it. Thirty times fifty is one thousand five hundred.

bash
cargo run

6. More params

Methods can take more parameters after self. can hold checks if another rectangle fits inside this one.

rust
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    fn square(size: u32) -> Self {
        Self { width: size, height: size }
    }
}

fn main() {
    let rect = Rectangle { width: 30, height: 50 };
    let small = Rectangle::square(10);

    println!("Area: {}", rect.area());
    println!("Square area: {}", small.area());
    println!("Can hold? {}", rect.can_hold(&small));
}

Output: Area: 1500 / Square area: 100 / Can hold? true

7. Associated fn

A function in impl without self is an associated function. We call it with two colons, like String colon colon from. square builds a new rectangle with equal sides.

8. Self

Capital Self is just a short name for the type we're implementing: Rectangle.

9. Run B

Let's run it. The square's area is one hundred, and yes, the big rectangle can hold it.

bash
cargo run

10. &mut self

To change the struct, a method takes ampersand mut self. scale multiplies both sides.

rust
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn scale(&mut self, factor: u32) {
        self.width *= factor;
        self.height *= factor;
    }
}

fn main() {
    let rect = Rectangle { width: 30, height: 50 };
    rect.scale(2);
    println!("Area after scaling: {}", rect.area());
}

Error in step 12:

text
error[E0596]: cannot borrow `rect` as mutable, as it is not declared as mutable
  --> src/main.rs:19:5
   |
19 |     rect.scale(2);
   |     ^^^^ cannot borrow as mutable
   |
help: consider changing this to be mutable
   |
18 |     let mut rect = Rectangle { width: 30, height: 50 };
   |         +++

Then line 18 becomes let mut rect = .... Output: Area after scaling: 6000

11. Call it

Let's call scale on our rectangle, and run it.

bash
cargo run

12. Error

Error: rect is not mutable, so we can't call a method that changes it. Again, the compiler tells us exactly what to do.

13. Fix

Let's add mut, and run again. Sixty times one hundred is six thousand.

bash
cargo run

Recap

To recap: methods live in an impl block. Ampersand self reads, ampersand mut self changes. Functions without self are associated functions, called with two colons.

ยฉ 2026 All Rights Reserved By Mahmudul Alam