Menu
Coddy logo textTech

Multiple Implementation Blocks

Part of the Object Oriented Programming section of Coddy's Rust journey — lesson 5 of 61.

Rust allows you to split a struct's methods across multiple impl blocks. While everything could go in a single block, separating them can make your code more organized and readable.

Here's a struct with its functionality split into two implementation blocks:

struct BankAccount {
    balance: f64,
}

// Constructor and basic queries
impl BankAccount {
    fn new(initial: f64) -> BankAccount {
        BankAccount { balance: initial }
    }
    
    fn balance(&self) -> f64 {
        self.balance
    }
}

// Transaction methods
impl BankAccount {
    fn deposit(&mut self, amount: f64) {
        self.balance += amount;
    }
    
    fn withdraw(&mut self, amount: f64) {
        self.balance -= amount;
    }
}

Both blocks work together seamlessly—Rust treats them as if they were one. You can call any method regardless of which block it's defined in:

fn main() {
    let mut account = BankAccount::new(100.0);
    account.deposit(50.0);
    println!("{}", account.balance()); // 150
}

This pattern becomes especially useful as your structs grow. You might group constructors together, keep read-only methods separate from mutating ones, or organize by feature. There's no limit to how many impl blocks a struct can have.

challenge icon

Challenge

Easy

Create a Player struct with two fields: name (String) and score (u32).

Organize the struct's methods across two separate implementation blocks:

First impl block — Constructor and query:

  • new — an associated function that takes a name: String and returns a Player with score set to 0
  • get_score — takes &self and returns the current score as u32

Second impl block — Score modifications:

  • add_points — takes &mut self and points: u32, adds the points to the score
  • reset_score — takes &mut self and sets the score back to 0

You will receive three inputs:

  • First line: the player's name (String)
  • Second line: points to add in the first round (u32)
  • Third line: points to add in the second round (u32)

Create a player using Player::new, add the first round points, print the score, then reset the score, add the second round points, and print the final score.

Expected output format:

{score_after_first_round}
{score_after_reset_and_second_round}

Cheat sheet

Rust allows splitting a struct's methods across multiple impl blocks for better organization:

struct BankAccount {
    balance: f64,
}

// First impl block
impl BankAccount {
    fn new(initial: f64) -> BankAccount {
        BankAccount { balance: initial }
    }
    
    fn balance(&self) -> f64 {
        self.balance
    }
}

// Second impl block
impl BankAccount {
    fn deposit(&mut self, amount: f64) {
        self.balance += amount;
    }
    
    fn withdraw(&mut self, amount: f64) {
        self.balance -= amount;
    }
}

All methods from different impl blocks work together seamlessly:

let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150

There's no limit to how many impl blocks a struct can have. This pattern is useful for grouping related functionality, such as separating constructors from mutating methods.

Try it yourself

use std::io;

// TODO: Define the Player struct with name (String) and score (u32) fields


// TODO: First impl block - Constructor and query methods (new, get_score)


// TODO: Second impl block - Score modification methods (add_points, reset_score)


fn main() {
    let mut input = String::new();
    
    // Read player name
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let name = input.trim().to_string();
    
    // Read first round points
    input.clear();
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let first_round: u32 = input.trim().parse().expect("Invalid number");
    
    // Read second round points
    input.clear();
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let second_round: u32 = input.trim().parse().expect("Invalid number");
    
    // TODO: Create a player using Player::new
    // TODO: Add first round points and print the score
    // TODO: Reset the score
    // TODO: Add second round points and print the final score
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming