Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot borrow vector as mutable because it is also borrowed as immutable when picking a value from a vector into another

I have this code:

use rand::seq::SliceRandom;
use std::ops::Range;

#[derive(PartialEq)]
struct Stack {
    settings: bool
}

fn generate_random_value(number: u8, cards: &mut Vec<Stack>) -> Vec<&Stack> {
    let mut overflow = vec![];
    for _ in (Range { start: 0, end: number } ) {
        let card = cards.choose(&mut rand::thread_rng()).unwrap();
        overflow.push(card);
        let elem = cards.iter().position(|x| x == card).unwrap();
        cards.remove(elem);
    };
    return overflow
}

fn main() {
    let stack_one = Stack {
        settings: true
    };

    let stack_two = Stack {
        settings: false
    };

    let mut vector = vec![stack_one, stack_two];
    let _gen_num = generate_random_value(2, &mut vector);
}

I need to remove an elem from the vector.

error[E0502]: cannot borrow `*cards` as mutable because it is also borrowed as immutable
  --> src/main.rs:15:9
   |
9  | fn generate_random_value(number: u8, cards: &mut Vec<Stack>) -> Vec<&Stack> {
   |                                             - let's call the lifetime of this reference `'1`
...
12 |         let card = cards.choose(&mut rand::thread_rng()).unwrap();
   |                    ------------------------------------- immutable borrow occurs here
...
15 |         cards.remove(elem);
   |         ^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
16 |     };
17 |     return overflow
   |            -------- returning this value requires that `*cards` is borrowed for `'1`

Playground

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are currently trying to store a reference to your card, put that reference into a new Vec, then remove the original card. That would leave an invalid reference. Instead of trying to collect references in your returned vector, push the actual object which was removed:

fn generate_random_value(number: u8, cards: &mut Vec<Stack>) -> Vec<Stack> {
    let mut overflow = vec![];
    for _ in 0..number { // `..` is a shorthand `Range` initialization
        let card = cards.choose(&mut rand::thread_rng()).unwrap();
        let elem = cards.iter().position(|x| x == card).unwrap();

        // `remove` returns the object it removed
        overflow.push(cards.remove(elem));
    };
    overflow
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading