scottd
scottd

Reputation: 1

Borrowing within a vector of structures

I have a vector of structures and i would like to update one structure with values in another. For my use case, I prefer to do it in a loop. I'm hitting the borrow-checker but it seems like there must be a simple solution to this type of problem.

#[derive(Debug)]
struct Column {
    header: String,
    amount: i32,
}

fn main() {
    let mut spreadsheet: Vec<Column> = Vec::new();

    spreadsheet.push(Column {
        header: "Car".to_string(),
        amount: 30300,
    });
    spreadsheet.push(Column {
        header: "House".to_string(),
        amount: 210800,
    });
    spreadsheet.push(Column {
        header: "Total".to_string(),
        amount: 0,
    });

    for column in &mut spreadsheet {
        //mutable borrow here
        if column.header == "Total" {
            column.amount = spreadsheet[0].amount //immutable borrow here
                        + spreadsheet[1].amount;
        } else {
            column.amount -= 300;
        }
    }

    for column in spreadsheet {
        println!("{:?}", column);
    }
}

Upvotes: 0

Views: 80

Answers (1)

Akiner Alkan
Akiner Alkan

Reputation: 6882

You are trying to set spreadsheet vector element while iterating inside of it. Since you always wanting to use spreadsheet[0].amount and spreadsheet[1].amount you can clone this values into another variable and work with them instead of using them inside of spreadsheet.

Here is the working code:

#[derive(Debug)]
struct Column {
    header: String,
    amount: i32,
}

fn main() {
    let mut spreadsheet: Vec<Column> = Vec::new();

    spreadsheet.push(Column {
        header: "Car".to_string(),
        amount: 30300,
    });
    spreadsheet.push(Column {
        header: "House".to_string(),
        amount: 210800,
    });
    spreadsheet.push(Column {
        header: "Total".to_string(),
        amount: 0,
    });

    let car_amount = spreadsheet[0].amount;
    let header_amount = spreadsheet[1].amount;

    spreadsheet.iter_mut().for_each(|column| {
        if column.header == "Total" {
            column.amount = car_amount + header_amount;
        } else {
            column.amount -= 300;
        }
    });

    for column in spreadsheet {
        println!("{:?}", column);
    }
}

Playground with using iter()

Since you want to do these operations in a for loop instead of iterator you can change the spreadsheet.iter_mut()... code block to the following:

for column in &mut spreadsheet {
    if column.header == "Total" {
        column.amount = car_amount + header_amount;
    } else {
        column.amount -= 300;
    }
}

Playground with using for loop

Upvotes: 1

Related Questions