ProgramGuru

Methods and associated functions

Methods and associated functions

A student record can expose operations that belong to its data, such as checking a target or applying a correction. An impl block defines methods and associated functions for a type. This keeps the operations close to the type they describe.

What you’ll learn

  • Choose &self, &mut self or self from the operation’s needs.
  • Distinguish an associated constructor from a receiver method.

Methods and associated functions in action

  1. Construct score 72

    New returns a Student with score 72.

    Construct score 72
  2. Mutable method stores 80

    Add_bonus borrows it mutably and stores 80.

    Mutable method stores 80
  3. Read method returns true

    Meets_target then borrows it for reading and returns true.

    Read method returns true
New returns a Student with score 72. Add_bonus borrows it mutably and stores 80. Meets_target then borrows it for reading and returns true. Neither method consumes the record.

Methods and associated functions explained

A method has a self parameter: &self borrows for reading, &mut self borrows for changes, and self takes ownership. An associated function without self is called through the type, such as Student::new. New is a naming convention rather than a special constructor keyword.

Work through the Rust program

Save the complete source as main.rs in the Rust environment. No standard input is needed.

Rust 2024 · complete program

struct Student { score: u32 }
impl Student {
  fn new(score: u32) -> Self { Self { score } }
  fn add_bonus(&mut self, bonus: u32) { self.score += bonus; }
  fn meets_target(&self) -> bool { self.score >= 75 }
}
fn main() {
  let mut student = Student::new(72);
  student.add_bonus(8);
  println!("Score: {}", student.score);
  println!("Target: {}", student.meets_target());
}

Expected output

Score: 80
Target: true

Follow the execution

New returns a Student with score 72. Add_bonus borrows it mutably and stores 80. Meets_target then borrows it for reading and returns true. Neither method consumes the record.

Try the complete program in the Rust compiler. For tests, Cargo commands and local files, use the specified local environment.

Try a small variation

Your task: Which receiver should a method use when it only checks the score?

Rust 2024 · complete program

struct Student { score: u32 }
impl Student {
  fn new(score: u32) -> Self { Self { score } }
  fn add_bonus(&mut self, bonus: u32) { self.score += bonus; }
  fn meets_target(&self) -> bool { self.score >= 75 }
}
fn main() {
  let mut student = Student::new(72);
  student.add_bonus(8);
  println!("Score: {}", student.score);
  println!("Target: {}", student.meets_target());
}

Worked answer

Use &self. The operation needs shared reading access, not ownership transfer or mutation permission.

Mistakes and limits to recognize

This small constructor does not validate its input. A production domain constructor can return Result to reject invalid marks. Do not use inheritance assumptions from other languages: Rust combines structs and traits rather than class inheritance.

Check your understanding

Which receiver should a method use when it only checks the score?
Choose one answer. You can try again.

Answer and explanation

Use &self.

Use &self. The operation needs shared reading access, not ownership transfer or mutation permission.

Take the idea into your next program

Use &self. The operation needs shared reading access, not ownership transfer or mutation permission. This small constructor does not validate its input.

Further reading: the official Rust Book on methods and associated functions.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Enums and optional values →