是否有可能将结构的一部分借用为可变,另一部分作为不可变结果 - 如果结构的字段是私有的。
fn main() {
let mut ecs = EntityComponentSystem::new();
for e_id in ecs.get_entities_with_component::<Velocity>().unwrap() {
let components = ecs.get_mut_components(e_id);
...
}
impl EntityComponentSystem {
...
pub fn get_entities_with_component<K: Key>(&self) -> Option<&HashSet<u64>> {
self.entities_with_components.get(&TypeId::of::<K>())
}
pub fn get_mut_components(&mut self, entity_id: u64) -> &mut TypeMap {
let entity = self.entities.get_mut(&entity_id).unwrap();
&mut entity.components
}
}
pub struct EntityComponentSystem {
entities: HashMap<u64, Entity>, <------- I would like to modify this.
entities_with_components: HashMap<TypeId, HashSet<u64>>, <---- while reading from this!
}
编译器给了我:
error[E0502]: cannot borrow `*ecs` as mutable because it is also borrowed as immutable
--> physics.rs:19:26
|
18 | for e_id in ecs.get_entities_with_component::<Velocity>() {
| --- immutable borrow occurs here
19 | let components = ecs.get_mut_components(*e_id);
| ^^^ mutable borrow occurs here
...
26 | }
| - immutable borrow ends here
我不理解的是,在我们基本上返回&self
字段的一部分之后,get_entities_with_component
中的entities_with_components
引用仍然是借用的。
不应该只借用那部分吗?有没有办法强制执行此操作?
答案 0 :(得分:2)
你只能将整个结构借用为不可变或可变,没有借用它的部分概念。当这成为问题时,您可以interior mutability:
的形式使用RefCelllpub struct EntityComponentSystem {
entities: RefCell<HashMap<u64, Entity>>,
entities_with_components: HashMap<TypeId, HashSet<u64>>,
}
现在你可以将整个struct借用为immutable,并将RefCell
的内容独立地作为可变内容借用:
pub fn get_mut_components(&self, entity_id: u64) -> &mut TypeMap {
let mut entities = self.entities.borrow_mut();
let entity = entities.get_mut(&entity_id).unwrap();
&mut entity.components
}
答案 1 :(得分:0)
不,函数不能返回对结构的一部分的引用,并使结构部分借用。
但是你可以像这样返回不可变和可变借位的元组
#[derive(Debug)]
struct AB(u32, u32);
impl AB {
fn borrow_parts(&mut self) -> (&u32, &mut u32) {
(&self.0, &mut self.1)
}
}
fn main() {
let mut ab = AB(0, 2);
{
let (a, b) = ab.borrow_parts();
*b = *a;
}
println!("{:?}", ab);
}