rust - 有没有办法从一个本身需要 &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 方法的引用。
解决方案
假设load
并且unload
不修改state.runmode
,您可以分为State
两部分:runmode
和nonrunmode
:
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
被修改。
推荐阅读
- swiftui - SwiftUI 也会导致死循环,为什么呢?
- javascript - 无法使用 ng 服务器运行 Angular 应用程序获取未找到模块
- asp.net-core - websocket 显示错误错误:正在调用的委托目标不再可用。请检查它是否已经过早地被GC'd.Uncaught
- html - 如何在 Notepad++ 中使用 regex(正则表达式)来删除所有不包含特定字符串的 HTML 和 JSON 代码?
- arrays - 将二维数组传递给函数并在 C 中编译时获取不兼容的指针类型
- ios - Swift 5.5 + Apple Core Data — 如何将简单的公式存储为 Core Data 中的项目/属性?
- java - 代码没有第二次抛出异常,尽管程序没有停止
- r - R中的逻辑运算符TRUE / FALSE
- javascript - TypeError:无法读取未定义的属性(读取“地图”)。当我尝试映射一组加密货币时引发错误
- nft - Solana Metaplex Candy Machine `tokenMint` 元数据为空