How do I pass a mutable vector as a function parameter in Rust?

mer219 picture mer219 · Aug 15, 2014 · Viewed 8.6k times · Source

I am implementing a small program that evaluates the Collatz conjecture. As part of this, I have a function that I call recursively that I want to store the current number being evaluated, determine if it is is a odd or even (or terminate if its just a 1), perform that branch of the conjecture and then call itself with the new number.

To do this, I wanted to pass a vector into this function and push the current number onto that vector, but I am having a tough time understanding how to pass a mutable vector reference.

Here is the code that I have:

fn evaluate_conjecture(number_to_be_evaluated: u64, mut intermediate_results: &Vec<u64>) -> u64 {
    intermediate_results.push(number_to_be_evaluated);

    if number_to_be_evaluated == 1 {
        0
    } else if number_to_be_evaluated % 2 == 1 {
        let odd_step_result = perform_odd_conjecture_step(number_to_be_evaluated);
        evaluate_conjecture(odd_step_result, intermediate_results) + 1
    } else {
        let even_step_result = perform_even_conjecture_step(number_to_be_evaluated);
        evaluate_conjecture(even_step_result, intermediate_results) + 1
    }
}

fn perform_odd_conjecture_step(_: u64) -> u64 {
    unimplemented!()
}

fn perform_even_conjecture_step(_: u64) -> u64 {
    unimplemented!()
}

and here is relevant part of my main

fn main() {
    let input_number = 42;
    let mut _intermediate_results: Vec<u64>;
    let number_of_steps = evaluate_conjecture(input_number, &_intermediate_results);
}

Here is the error I am getting

error[E0596]: cannot borrow `*intermediate_results` as mutable, as it is behind a `&` reference
 --> src/main.rs:2:5
  |
1 | fn evaluate_conjecture(number_to_be_evaluated: u64, mut intermediate_results: &Vec<u64>) -> u64 {
  |                                                                               --------- help: consider changing this to be a mutable reference: `&mut std::vec::Vec<u64>`
2 |     intermediate_results.push(number_to_be_evaluated);
  |     ^^^^^^^^^^^^^^^^^^^^ `intermediate_results` is a `&` reference, so the data it refers to cannot be borrowed as mutable

How do I pass this vector into the function so I can modify it each time the function is called?

Answer

Chris Morgan picture Chris Morgan · Aug 15, 2014

&T is an immutable reference.

&mut T is a mutable reference.

Change your &Vec<u64> to &mut Vec<u64> and your &_intermediate_results to &mut _intermediate_results.

This is a thing which is fairly well documented; I suggest you read the documentation if you haven’t — it explains quite a lot. There's a section specifically about mutable references.