Mutate self while iterating through vec in self

Hello,
before aksing this I want to say that I know why this is not working. I would like to find a different way to do this or maybe a workaround.
I have a GUI struct with a vec of buttons. In the handle_input method I would like to iterate over all buttons and call the handle_click function which mutates the gui (basically self).
Playground

Code:

fn main() {
    let mut gui = GUI { close: false, buttons: vec![Button { text: "".to_string() },Button { text: "".to_string() },Button { text: "".to_string() },Button { text: "".to_string() }] };
    gui.handle_input();
}

struct GUI {
    close:bool,
    buttons: Vec<Button>
}

impl GUI {
    pub fn handle_input(&mut self) {
        for but in self.buttons.iter_mut() {
            but.handle_click(self);
        }
    }
}

struct  Button {
    text:String
}

impl Button {
    fn handle_click(&mut self, gui:&mut GUI ){
        gui.close = true;
    }
}

I know that I can not borrow self again because I am iterating mutably over it, but I have no clue how to this different.

I hope you can help me or show me a different way to do this.

The solution to this class of problems is to use interior mutability.

&mut is for exclusive access, but you can also mutate things using & shared references if you wrap mutated objects in Cell/Atomic or RefCell/Mutex.

Alternatively, split the struct into two. Instead of but.handle_click(self) use but.handle_click(self.part_that_buttons_can_access).

In case of callbacks/handlers, you can also never give them any reference at all. Have them return what they want to do, e.g. instead of gui.close = true, make them return Action::Close.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.