2

I have a struct containing a vector whose elements must be able to modify other elements in the vector.

I tried doing it like this:

use core::cell::RefCell;

struct Go {
    car: i32,
}

impl Go {
    pub fn attack(&mut self, val: &mut Self) {
        val.car = self.car;
        self.car = 5;
    }
}

struct World {
    pub params: RefCell<Vec<Go>>,
    pub val: i32,
}

fn main() {
    let world = World {
        params: RefCell::new(vec![]),
        val: 42,
    };

    for m in 0..10 {
        world.params.borrow_mut().push(Go { car: m });
    }

    world.params.borrow()[5].attack(&mut world.params.borrow()[6]);
}

playground

However , I got these errors

error[E0596]: cannot borrow data in a dereference of `std::cell::Ref<'_, std::vec::Vec<Go>>` as mutable
  --> src/main.rs:29:5
   |
29 |     world.params.borrow()[5].attack(&mut world.params.borrow()[6]);
   |     ^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::cell::Ref<'_, std::vec::Vec<Go>>`

error[E0596]: cannot borrow data in a dereference of `std::cell::Ref<'_, std::vec::Vec<Go>>` as mutable
  --> src/main.rs:29:42
   |
29 |     world.params.borrow()[5].attack(&mut world.params.borrow()[6]);
   |                                          ^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::cell::Ref<'_, std::vec::Vec<Go>>`

How do I get this done? also please note that Due to some constraints , I do not want to create any extra variables in the main function.

The attack function works like an update function for different elements of the vec in the main program I am supposed to be running

  • Welcome to Stack Overflow! It looks like your question might be answered by the answers of [How to get mutable references to two array elements at the same time?](https://stackoverflow.com/q/30073684/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Mar 30 '20 at 20:00
  • The duplicate [applied to your situation](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cb3f07a88923776f8e6bb42ee5889eeb). – Shepmaster Mar 30 '20 at 20:04
  • The problem is that , I have to keep pushing and removing elements from the world struct for the actual program I am running, of which this is a sample.And I don't want to create any extra variables in the main function – Javid Farhan Mar 30 '20 at 20:06
  • Then perhaps [How to mutate another item in a vector, but not the vector itself, while iterating over the vector?](https://stackoverflow.com/q/35823029/155423) or [Efficiently mutate a vector while also iterating over the same vector](https://stackoverflow.com/q/49143770/155423). – Shepmaster Mar 30 '20 at 20:11
  • *I don't want to create any extra variables* — this doesn't have any objective purpose. Variables don't "cost" anything other than a few more bytes in the uncompiled source code file. – Shepmaster Mar 30 '20 at 20:12
  • Theyd o not work when the vector is in a struct , and is there no way to implement Deref (also, will it work?) ? And not wanting to use extra variables is because I might have to do the attack() function on more than 2 variables.(For which I will modify the function definition) – Javid Farhan Mar 30 '20 at 20:19
  • Please **[edit]** your post to contain links to the questions you have read along with the reasons that they are invalid duplicates. Comments are ephemeral. – Shepmaster Mar 30 '20 at 20:21
  • Making it into a `Vec>` [will definitely work](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0ae3c70d553712cb62f0682ecc2a2f7e) — why wouldn't it? – Shepmaster Mar 30 '20 at 20:25
  • but https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2b5639ed08657595193aa57cc5bd07a5 this does not .Shouldn't they be the same ? – Javid Farhan Mar 30 '20 at 20:39
  • That's actually a known issue where the compiler mistakenly picks `IndexMut` where `Index` would suffice. See [Why can I not call borrow_mut() after indexing into an immutable Vec?](https://stackoverflow.com/q/52989901/3650362) You can fix it by writing `{world.params[6].borrow_mut()}` in curlies. – trent Mar 30 '20 at 21:12
  • That solved it , Thank you guys! – Javid Farhan Mar 31 '20 at 09:49
  • In that case, can you click the button to agree with the duplicate that solved your problem? Questions marked as duplicates can help future askers find the answers to their questions more quickly. Thanks! – trent Apr 01 '20 at 14:13
  • Should I edit to show what I reached in the end , that made it work ? – Javid Farhan Apr 01 '20 at 14:30
  • If what you did is basically what's mentioned at the linked question, I wouldn't add anything. If you did something special that isn't covered by the other question's answers, the best thing to do would be to add an answer to the *other* question, so that all the answers are collected in one place (it makes it easier to find and update them). – trent Apr 01 '20 at 14:40

0 Answers0