Consider the following code:
struct Event {
id: i32,
}
struct EventsLoop;
impl EventsLoop {
pub fn new() -> EventsLoop {
EventsLoop {}
}
pub fn poll_events<F>(&mut self, _callback: F)
where
F: FnMut(Event),
{
// gets event and passes it to the callback
}
}
struct Store {
events_loop: EventsLoop,
running: bool,
}
fn main() {
let store = setup_store();
run_app(store);
}
fn setup_store() -> Store {
Store {
events_loop: EventsLoop::new(),
running: true,
}
}
fn run_app(mut store: Store) {
let mut e_loop = store.events_loop;
e_loop.poll_events(|event| {
// poll_events needs EventsLoop as a mutable reference
match event {
Event { id: -1 } => {
store.running = false;
}
_ => { /* store is used in other events */ }
}
})
}
This causes the compiler to complain:
error[E0382]: capture of partially moved value: `store`
--> src/main.rs:38:24
|
37 | let mut e_loop = store.events_loop;
| ---------- value moved here
38 | e_loop.poll_events(|event| {
| ^^^^^^^ value captured here after move
|
= note: move occurs because `store.events_loop` has type `EventsLoop`, which does not implement the `Copy` trait
I have a closure that needs to either borrow or take ownership of store
. At the same time I need store.events_loop
as a mutable reference (because of its method poll_events
). I thought that maybe I could get around the multiple mutable borrowing problem by passing ownership of the EventsLoop
from store
to the function scope. So my first question is:
- Can this problem be solved by somehow moving the
EventsLoop
out ofstore
?
Another solution I thought of was passing store
to run_app
as an immutable reference, and wrapping the field running
in a Cell
, but then I would need some kind of smart pointer to get the EventsLoop
as a mutable reference. So that leads me to my second question:
- Is there a way to extract
events_loop
fromstore
as a mutable reference whenstore
was passed as an immutable reference?
Edit:
My apologies for not having an MVCE in my first post. The current example should reproduce the problem.
It has been suggested this question may be duplicate to Mutably borrow one struct field while borrowing another in a closure
The situation here is similar but different.
The question in the link is about two fields in a struct, using one field from a struct in a closure that is passed to a method on the other field.
This question is about using a struct in a closure, that closure being passed to a method of a field inside that struct.
The point here is that I would like to be able to access the store in the closure, while also getting the events loop from the store. The idea is that all data structures created at initialization in setup_store
- including the events loop - go into a single struct.