Mik*_*nko 6 ownership rust borrow-checker
我有一个MainStruct拥有 的实例HelperStruct。我想创建一个调用helper's 方法的方法。但helpers 方法确实需要(不可变)访问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();
}
}
Run Code Online (Sandbox Code Playgroud)
通过这个设置,我得到
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
Run Code Online (Sandbox Code Playgroud)
至关重要的是,它MainStruct仍然是与功能交互的主要接口(因此拥有 Helper 自己的 Main 不是一个选项)。
我应该如何重构我的代码(或者可能使用智能指针?),以便我可以从 Helper 内部与所有者进行交互?另外,保证the_method()只会在 的实例内调用MainStruct。
这MainStruct是Field我的游戏。是HelperStruct负责路径的类,主要是 A*。A* 有许多存储其状态的大型数组。A* 通过后,只有其中一些需要重新初始化(或以其他方式清理)。
我最终多次调用 A*,因此我想避免每次传递时都完全重新初始化它。所以我将其存储在 中Field,并且仅reset()在通过后调用。
为了正确规划路径,A* 需要查看Field(障碍物等)。当 A* 正在运行时,它当然会改变它自己的一些领域,所以the_method,实际上
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
Run Code Online (Sandbox Code Playgroud)
需要有一个&mut self
你需要让 Rust 相信,无论用HelperStruct做什么MainStruct,它都不会尝试通过访问自身,因为这构成了对你也有 MainStruct可变引用的东西的不可变引用。
根据 的复杂性和需求HelperStruct,一种选择是将swap虚拟HelperStruct值放入其中MainStruct,然后调用(现已隔离的)上的函数HelperStruct。
use std::mem::swap;
struct MainStruct {
helper: HelperStruct,
}
impl MainStruct {
pub fn call_helper(&mut self, args) {
let mut helper_struct = HelperStruct::default(); // Some dummy value
swap(&mut helper_struct, &mut self.helper);
helper_struct.the_method(self, args);
swap(&mut helper_struct, &mut self.helper);
}
}
Run Code Online (Sandbox Code Playgroud)
这样,就可以对除自身之外的HelperStruct.the_method所有内容进行不可变的访问,该访问已被暂时排除。完成后,我们将值交换回来,这不会造成任何损害。MainStruct
| 归档时间: |
|
| 查看次数: |
497 次 |
| 最近记录: |