首页 > 解决方案 > 有没有办法从一个本身需要 &mut self 的方法中传递 &mut self ?

问题描述

我有这个State包含一个Box<dyn Runmode>. 运行模式应该能够被切换,并且当它被切换时,旧的运行模式被卸载(它释放它的资源并重置一些状态),然后包含运行模式的框被重新分配,并且新的运行模式被加载。加载运行模式时,它必须能够访问State结构以修改和/或读取一些对运行模式正常工作至关重要的内容,并且在卸载时它必须能够重置该状态。这是我的代码:

trait Runmode {
    fn load(&mut self, state: &mut State);
    ...
    fn unload(&mut self, state: &mut State);
}

struct State {
    runmode: Box<dyn Runmode>,
    ...
}

impl State {
    pub fn set_runmode(&mut self, mut new_runmode: Box<dyn Runmode>) {
        self.runmode.unload(self);
        // the line above causes errors

        self.runmode = new_runmode;

        self.runmode.load(self);
        // this line also causes errors
    }
}

如您所知,这会导致对单个对象的多个可变引用的问题,这是不允许的。但我真的没有看到解决这个问题的另一种方法。地狱,即使这样也不会编译:

fn switch_runmode(mut state: State, mut new_runmode: Box<dyn Runmode>) {
    state.runmode.unload(&mut state);

    state.runmode = new_runmode;

    state.runmode.load(&mut state);
}

我在这里忘记了什么?在第二个示例中,它还说我借用了 mutable 两次,但我所做的唯一可变借用是在我加载和卸载运行模式时,然后只有一个可变引用,即进入 runmodes 方法的引用。

标签: rustownership

解决方案


假设load并且unload不修改state.runmode,您可以分为State两部分:runmodenonrunmode

struct State {
    runmode: Box<dyn Runmode>,
    nonrunmode: NonRunMode, // contains everything else
}

然后,unload并且load可以&mut NonRunMode作为论据。

trait Runmode {
    fn load(&mut self, state: &mut NonRunMode);
    ...
    fn unload(&mut self, state: &mut NonRunMode);
}

这应该让编译器清楚地知道只有不同的部分State被修改。


推荐阅读