Having a child modify its parent

早过忘川 提交于 2021-01-28 12:33:50

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/28323968/having-a-child-modify-its-parent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!