9.5 Methods and Associated Functions

Rust defines behavior for structs in impl blocks, separating data (fields) from methods or associated functions.

9.5.1 Associated Functions

Associated functions do not operate directly on a struct instance and are similar to static methods in languages like C++ or Java. They are commonly used as constructors or utility functions:

impl Person {
    fn new(name: String, age: u8) -> Self {
        Person { name, age }
    }
}

fn main() {
    let person = Person::new(String::from("Frank"), 40);
}

Here, Person::new is an associated function that constructs a Person instance. The :: syntax is used to call an associated function on a type rather than an instance, distinguishing it from methods that operate on existing values.

9.5.2 Methods

Methods are functions defined with a self parameter, allowing them to act on specific struct instances:

impl Person {
    fn greet(&self) {
        println!("Hello, my name is {}.", self.name);
    }
}

There are three primary ways of accepting self:

  • &self: an immutable reference (read-only)
  • &mut self: a mutable reference
  • self: consumes the instance entirely
struct Person {
    name: String,
    age: u8,
}

impl Person {
    fn greet(&self) {
        println!("Hello, my name is {}.", self.name);
    }

    fn set_age(&mut self, new_age: u8) {
        self.age = new_age;
    }

    fn into_name(self) -> String {
        self.name
    }
}

fn main() {
    let mut person = Person {
        name: String::from("Grace"),
        age: 35,
    };

    person.greet();                 // uses &self, read-only access
    person.set_age(36);             // uses &mut self, modifies data
    let name = person.into_name();  // consumes the person instance
    println!("Extracted name: {}", name);

    // `person` is no longer valid here because it was consumed by into_name()
}