Labs ICT
โญ Pro Login

Methods and impl

Adding behavior to your structs.

Basic Methods

Structs are great for holding data, but you'll often want to define behavior on them too. That's where methods come in. You write methods inside an impl block, and the first parameter is always some version of self.

struct Rectangle {
    width: f64,
    height: f64,
}

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

fn main() {
    let rect = Rectangle {
        width: 10.0,
        height: 5.0,
    };

    println!("Area: {}", rect.area());
}
Try it Yourself ->

self, &self, and &mut self

You can choose how methods take ownership of self. Use &self for read-only access, &mut self for modifications, or just self when you want the method to consume the instance entirely. Most of the time, you'll use &self or &mut self.

struct Counter {
    value: i32,
}

impl Counter {
    fn increment(&mut self) {
        self.value += 1;
    }

    fn reset(self) -> i32 {
        self.value
    }
}

fn main() {
    let mut c = Counter { value: 0 };
    c.increment();
    println!("{}", c.value);
}
Try it Yourself ->

Associated Functions

Associated functions don't take self as a parameter, so they're tied to the type itself rather than an instance. The most common use is a constructor โ€” think ::new() on String or Vec.

struct Circle {
    radius: f64,
}

impl Circle {
    fn new(radius: f64) -> Circle {
        Circle { radius }
    }

    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}

fn main() {
    let circle = Circle::new(5.0);
    println!("Area: {:.2}", circle.area());
}
Try it Yourself ->

Multiple impl Blocks

Rust allows you to write multiple impl blocks for the same struct. This is especially useful when working with generics and traits, where different implementations apply to different constraints. For simple structs, you usually stick with one block.

struct Dog {
    name: String,
}

impl Dog {
    fn bark(&self) {
        println!("{} says: Woof!", self.name);
    }
}

impl Dog {
    fn sit(&self) {
        println!("{} sits.", self.name);
    }
}

fn main() {
    let dog = Dog { name: String::from("Rex") };
    dog.bark();
    dog.sit();
}
Try it Yourself ->

๐Ÿงช Quick Quiz

Where are methods defined for structs?