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`
CodePudding user response:
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
}