1

Sorry for the complex title, it's difficult to summarize my problem. Here it is :

I wish to iterate over a Vec of struct and modifiy elements in the process. But my struct has a Vec and Vec dosen't implement Copy. I tried many things but I never succeed. And I think it's because I don't realy understand the problem...

A naive exemple :

fn main() {
    let obj_0 = Obj{id: 0, activated: false, obj_list: [1].to_vec()};
    let obj_1 = Obj{id: 1, activated: false, obj_list: [].to_vec()};
    let obj_2 = Obj{id: 2, activated: false, obj_list: [0, 1].to_vec()};
    let obj_3 = Obj{id: 3, activated: false, obj_list: [2, 4].to_vec()};
    let obj_4 = Obj{id: 4, activated: false, obj_list: [0,1,2].to_vec()};
    let obj_5 = Obj{id: 5, activated: false, obj_list: [1].to_vec()};
    let mut objs: Vec<Obj> = [obj_0, obj_1, obj_2, obj_3, obj_4, obj_5].to_vec();

    //loop {
        objs[0].activated = true;
        for o in objs{
            if o.id == 1 || o.id == 2 {
                let mut o2 = objs[o.id];
                o2.activated = true;
                objs[o.id] = o2;
            }
        }
    //}
}

#[derive (Clone)]
struct Obj {
  id: usize,
  activated: bool,
  obj_list: Vec<i32>,
}

(Playground)

error[E0382]: borrow of moved value: `objs`
  --> src/lib.rs:14:30
   |
8  |     let mut objs: Vec<Obj> = [obj_0, obj_1, obj_2, obj_3, obj_4, obj_5].to_vec();
   |         -------- move occurs because `objs` has type `std::vec::Vec<Obj>`, which does not implement the `Copy` trait
...
12 |         for o in objs{
   |                  ----
   |                  |
   |                  value moved here
   |                  help: consider borrowing to avoid moving into the for loop: `&objs`
13 |             if o.id == 1 || o.id == 2 {
14 |                 let mut o2 = objs[o.id];
   |                              ^^^^ value borrowed here after move

error[E0507]: cannot move out of index of `std::vec::Vec<Obj>`
  --> src/lib.rs:14:30
   |
14 |                 let mut o2 = objs[o.id];
   |                              ^^^^^^^^^^
   |                              |
   |                              move occurs because value has type `Obj`, which does not implement the `Copy` trait
   |                              help: consider borrowing here: `&objs[o.id]`

ANSWER : Thanks to trentcl to solve this with adding &mut to iterator and simplified the case, I was going too complex. Playgroud here.

        for o in &mut objs{
            if o.id == 1 || o.id == 2 {
                o.activated = true;
            }
        }
Edrae
  • 43
  • 2
  • 6
  • 1
    Does this answer your question? [How can you iterate and change the values in a mutable array in Rust?](https://stackoverflow.com/questions/56963011/how-can-you-iterate-and-change-the-values-in-a-mutable-array-in-rust) – trent Mar 19 '20 at 18:06
  • You need to iterate over `objs` by (mutable) reference if you don't want to move its values. The linked question uses `iter_mut` but you can also iterate over `&mut objs`. I'm not quite sure I get what you're doing with the `id`s, but here's that idea applied to your problem: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=88e9e28f6caf67fe8cd9017afd62169d – trent Mar 19 '20 at 18:07
  • Other related questions: [Does &mut do anything when declaring a for loop variable?](https://stackoverflow.com/q/40834969/3650362) and [Mutable structs in a vector](https://stackoverflow.com/q/23585651/3650362) – trent Mar 19 '20 at 18:08
  • @trentcl Considering that this code borrows two elements at the same time with different mutability constraints, those suggestions might not be enough here (that Playground does not compile either, did you intend to modify it in some way?). – E_net4 Mar 19 '20 at 18:13
  • @E_net4 yes, sorry, I meant [this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cb33320d23ad212ac3308f8c277f57d0). The original code only tries to borrow the same element twice, so I made the obvious simplification. There may be more going on, indeed. – trent Mar 19 '20 at 18:28
  • Thx all ! @trentcl I will look at you're proposition, it seems that you're right (I really hope). – Edrae Mar 19 '20 at 18:40
  • @E_net4 I tried so maaaany things... With &mut or iter_mut() or other. – Edrae Mar 19 '20 at 18:41
  • Okay ! It works on my real case !! So, the solution of @trentcl is the one we need, I edit my post to add it. I already tested the "&mut" but not exactly as this. – Edrae Mar 19 '20 at 18:52

0 Answers0