Course contentsShow
← Rust
Lesson 47 of 1,9101. Rust Fundamentals and ToolingFree lesson

Defining Methods and Constructors

Associate behavior with data structures using implementation blocks.

In this lesson, you will learn how to attach functions directly to your custom struct types to define their behavior and create new instances.

The impl Block

In Rust, we don't define methods inside the struct definition itself. Instead, we use an impl (implementation) block. This keeps your data structure (the fields) separate from its logic (the methods).

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

impl Rectangle {
    // This is a method because it takes &self
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

By using &self as the first parameter, the method gains access to the instance it was called on. You would call this using dot notation: let my_rect = Rectangle { width: 10, height: 5 }; println!("{}", my_rect.area());.

Constructors

Rust does not have a special constructor keyword like some other languages. Instead, it is idiomatic to define a static method (often named new) within your impl block that returns an instance of your struct.

Notice that this function does not take self as a parameter:

impl Rectangle {
    fn new(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
}

You call this "associated function" using the double-colon syntax, which signifies that the function belongs to the type itself rather than a specific instance: let rect = Rectangle::new(10, 5);.

Why separate them?

This separation of concerns is a core tenet of Rust. By grouping related logic inside impl blocks, your code becomes easier to navigate. Any function inside an impl block that takes &self, &mut self, or self is considered a method, while functions without self (like new) are associated functions. Both are used to organize the functionality of your data structures cleanly and predictably.

Key Takeaway: Use an impl block to define methods (which use &self to operate on instances) and associated functions (like new) to initialize your custom types.