这个问题与编译器为什么会给出这些错误无关-我想我理解这一点。这个问题是关于如何在可变路径上管理情况,同时希望能够调用其他功能。
这是我正在尝试做的简化。 Foo
中有很多World
,我需要根据World
中的其他数据更新它们。我希望能够在World
内调用几个私有函数。
pub struct Foo {
id: i32,
//...
}
pub struct Bar {
//...
}
pub struct World {
foos: Vec<Foo>,
bars: Vec<Bar>,
//...
}
impl World {
pub fn create() -> World {
World {
foos: Vec::new(),
bars: Vec::new(),
}
}
pub fn update(&mut self) {
for foo in self.get_foos_mut() {
//error[E0XXX]: cannot borrow `*self` as mutable/imutable ...
let _bar = self.get_bar_given_foo(foo);
//alter foo based on bar and other world things calling other world functions...
//...
}
}
//some useful utility functions that should be called several times
//from different World places...
fn get_foos_mut(&mut self) -> &mut [Foo] {
//select slice interval based on foos or any other calculation using self data...
&mut self.foos[..]
}
fn get_bar_given_foo(&self, foo: &Foo) -> &Bar {
//select bar based on foo or any other calculation using self data...
&self.bars[foo.id as usize]
}
//other utility functions that abstract e sequence of operations that I would
//like to use on the update path...
}
fn main() {
let mut world = World::create();
world.update();
}
您也可以run the code。
这看起来非常局限,因为在update
函数这样的可变路径上,我无法从self
调用任何私有方法。
由于我不想克隆所有数据,因此我想到了三种解决方案。我尝试过1和2都可以。
内联所有内容。由于此解决方案适用于上面的示例,因此编译错误似乎是由于Rust编译器的限制所致,据我所知:它只是查看函数签名而不是函数的实现。
创建接收所需内容引用的功能。无需再次借用self
。可以删除功能World::get_foos_mut(&mut self) -> &mut [Foo]
并在World
外部创建一个新函数:fn world_get_foos_mut(foos: &mut Vec<Foo>) -> &mut [Foo]
playground上的代码显示了此解决方案。
创建宏而不是常规函数??由于它们是宏,我怀疑其中不会涉及任何借用。由于我不熟悉宏,因此无法确定它是否有效或如何执行。
我真的需要其他选择,因为我认为解决方案1不可行,解决方案2看起来非常麻烦且脆弱(看起来我可能有相同的问题,但引用World
中)。
我对于无法找到正确的模型来处理此问题感到非常沮丧。
Rust编译器将来会尝试分析这些情况吗?