I have a MainStruct which owns an instance of HelperStruct. I want to make a method that calls helper's method. But the helper's method really needs (immutable) access to MainStruct
struct MainStruct {
helper: HelperStruct,
}
impl MainStruct {
pub fn call_helper(&mut self, args) {
// &mut self because the_method changes inner state of HelperStruct
self.helper.the_method(self, args)
}
}
impl HelperStruct {
pub fn the_method(&mut self, owner: &MainStruct, args) {
owner.other_method();
}
}
With this setup, I'm getting
error[E0502]: cannot borrow `self.helper` as mutable because it is also borrowed as immutable
214 | self.helper.the_method(self, args)
| ^^^^^^^^^^^^----------^----^^^^^^^^^^^^^^^^^^^^^^
| | | |
| | | immutable borrow occurs here
| | immutable borrow later used by call
| mutable borrow occurs here
It is crucial that the MainStruct remains the primary interface for interaction with the functionality (so having Helper own Main isn't an option).
How should I restructure my code (or maybe use smart pointers?) so that I can interact with the owner from the inside of Helper?
Also, it is guaranteed that the_method() will only be called inside an instance of MainStruct.
The MainStruct is the Field of my game. The HelperStruct is the class that takes care of pathing, A* mostly. A* has a number of large arrays that store its state. After an A* pass only some of them need to be reinitialized (or otherwise cleaned).
I end up calling A* a lot of times, so I want to avoid fully reinitializing it for every pass. So I store it in Field, and only call reset() after a pass.
To path plan properly, A* needs to look at the Field (obstacles, etc). While the A* is going, it of course changes some of its own fields, so the_method, being actually
pub fn full_pathing(&mut self, field: &Field, source: (i32, i32), destination: (i32, i32))
needs to have a &mut self
You can make the_method an associated function, and have it only receive a &mut MainStruct. It will have to access itself through that reference:
struct MainStruct {
helper: HelperStruct,
}
impl MainStruct {
pub fn call_helper(&mut self, args) {
HelperStruct::the_method(self, args)
}
}
impl HelperStruct {
pub fn the_method(main: &mut MainStruct, args) {
main.other_method();
//Access helper like this:
main.helper.whatever();
}
}
Alternatively, if your two structs are so intertwined, you could combine them into a single struct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With