Reputation: 304
I want to have a child struct modify its parent struct. Example:
// Problem: Having a struct's field modify the struct in which the field is.
// MUST NOT be copyable nor clonable
struct Updatee {
value: u64,
updater: Updater
}
impl Updatee {
fn update(&mut self) {
// ERROR: cannot borrow `*self` as mutable more than once at a time
self.updater.update(self);
}
}
// MUST NOT be copyable nor clonable
struct Updater {
value: u64
}
impl Updater {
fn update(&mut self, updatee: &mut Updatee) {
self.value = self.value + 1;
updatee.value = self.value;
}
}
fn main() {
let updater = Updater { value: 0 };
let updatee = Updatee { value: 0, updater: updater };
updatee.update();
updatee.update();
assert_eq!(2, updatee.value);
}
I'm sure it can be done with unsafe blocks, but is there an alternative?
Perhaps my code is not idiomatic?
Upvotes: 1
Views: 233
Reputation: 13667
The reason you are getting the "already borrowed" error is because you are trying to pass the Updater
to its update
method twice, once as self
, and once embedded inside of updatee
. For memory safety reasons, Rust doesn't allow that.
The simplest solution would be to pass to update
a reference to the field in Updatee
that needs to be updated rather than the entire Updatee
:
impl Updater {
fn update(&mut self, updatee_value: &mut u64) {
self.value = self.value + 1;
*updatee_value = self.value;
}
}
If multiple fields need to be updated, Updatee
could be transformed into a wrapper around the Updater
and another struct that holds the fields with the actual data, which could be safely passed to update
.
Upvotes: 4