Running function in a loop with moved value

Hello,

I'm sorry if this is a common question. I am using a library (egui_grid) in order to make a grid with a variable number of rows and columns, so I am attempting to spawn them in a for loop:

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            let grid = GridBuilder::new();
            for i in 0..self.height {
                grid.new_row(Size::exact(200.0));
            }
        });
    }
}

However, this gives the following error:

use of moved value: `grid`
value moved here (where I add the row), in previous iteration of loop

The library unfortunately does not have a function to add a list of rows at once, so that is not an option. Due to the limited method options (no hate to the library, it is a pretty small one), I believe I have to spawn them inside the loop.

I tried calling .borrow_mut() on the grid and attempting to add the row to that, but that gave me more or less the same error. I'm not really sure why I thought that would work in the first place, but I thought it was worth a shot?

Thank you for any help :slight_smile:

Always provide full compiler errors if you can, instead of the shortened IDE-version.

Sorry!! I was worried the errors would be too ugly, this is the full one:

error[E0382]: use of moved value: `grid`
  --> src/main.rs:43:17
   |
41 |             let grid = GridBuilder::new();
   |                 ---- move occurs because `grid` has type `GridBuilder`, which does not implement the `Copy` trait
42 |             for i in 0..self.height {
   |             ----------------------- inside of this loop
43 |                 grid.new_row(Size::exact(200.0));
   |                 ^^^^ value moved here, in previous iteration of loop
   |
help: consider cloning the value if the performance cost is acceptable
   |
43 |                 grid.clone().new_row(Size::exact(200.0));
   |                     ++++++++

Looking at the API docs… assuming it’s this function[1]

pub fn new_row(self, size: Size) -> Self

it looks like you need to use this one like

let mut grid = …;
for … {
    grid = grid.new_row(Size::exact(200.0));
}

to make it work in a loop. (In particular, not using the output of the function would rarely be sensible.)


  1. linking relevant docs can also be helpful to make a question easier to answer :wink: ↩︎

That's sort of embarrassing, such an obvious solution... Thank you!!

Just for fun, this function makes it easy to write the same thing but with fold:

let grid = (0..self.height).fold(GridBuilder::new(), |grid, i| {
    grid.new_row(Size::exact(200.0))
});
4 Likes

I... Honestly didn't know that was a function lmao, thank you!