-4

I'm having trouble reading from and appending to a vector. I only want a reference to an element from a vector temporarily to create a new Object. It doesn't need to be modified, then the Object doesn't need to be referenced and can go back to being a vector element, with the new Object I want to push it to the end of the vec.

use rand::Rng;

struct Object {
  num: u64
}

impl Object {
  fn init() -> Self {
    return Self {
      num: rand::thread_rng().gen_range(0..100)
    }
  }

  fn new(element_1: &Object, element_2:&Object) -> Option<Self> {
    if element_1.num < 1000 && element_2.num < 1000 {
      let _self = Self {
        num: (element_1.num + element_2.num)
      };
      return Some(_self);
    }
    return None
  }
}

fn main () {
  let mut vec: Vec<Object> = Vec::new();
  for x in (0..20) { vec.push(Object::init()) }
  let mut x = 0;
  let y = 10;
  let mut element_1 = &Object::init(); 
  let mut element_2 = &Object::init();
  let mut reverse_walker = vec.len() - 1;
  // cannot borrow `vec` as mutable because it is also borrowed as immutable
  while x < y {
    let index = rand::thread_rng().gen_range(0..(vec.len()-1) as usize);
    match vec.get(index) { // immutable borrow occurs here
      Some(element) => {
        element_1 = element;
      },
      None => ()
    }
    match vec.get(reverse_walker) {
      Some(element) => {
        element_2 = element;
      },
      none => ()
    }

    reverse_walker = reverse_walker - 1;
    if reverse_walker == 0 {
      reverse_walker = vec.len() - 1;
    }

    let new_element: Option<Object> = Object::new(&element_1, &element_2);
    match new_element {
      Some(element) => {
        vec.push(element); // mutable borrow occurs here
      },
      None => ()
    }

    x = x + 1;
  }
}

I am getting the error:

error[E0502]: cannot borrow `vec` as mutable because it is also borrowed as immutable
  --> src/main.rs:57:9
   |
36 |     match vec.get(index) { // immutable borrow occurs here
   |           -------------- immutable borrow occurs here
...
54 |     let new_element: Option<Object> = Object::new(&element_1, &element_2);
   |                                                   ---------- immutable borrow later used here
...
57 |         vec.push(element); // mutable borrow occurs here
   |         ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
John Kugelman
  • 330,190
  • 66
  • 504
  • 555
svnty
  • 7
  • 1
  • 6
  • 1
    It's a surprising and unfortunate fact that IDE errors are not nearly as good as Cargo's. Pro Rust tip, if you're confused by an error go see what `cargo check` says. It almost always has more information and can often even recommend a fix. – John Kugelman Jun 01 '22 at 00:34
  • @JohnKugelman Actually, where rustc suggets a fix rust-analyzer does it too (because it borrows the error from rustc) - but it may be hidden and hard to reveal. – Chayim Friedman Jun 01 '22 at 00:35
  • Does this answer your question? [Cannot borrow as mutable because it is also borrowed as immutable](https://stackoverflow.com/questions/47618823/cannot-borrow-as-mutable-because-it-is-also-borrowed-as-immutable) – MeetTitan Jun 01 '22 at 00:41
  • My solution was to use a temporary vector at the level of element_1 and element_2, then append it to the first vector out of the loop. It's resource intensive and slows the program substantially but I can't find any other solutions. – svnty Jun 01 '22 at 03:24

0 Answers0