rust - 是否可以借用结构的一部分作为可变部分而其他部分作为不可变部分?

标签 rust borrow-checker

是否可以借用结构的一部分作为可变部分,而另一部分作为不可变部分 - 如果结构的字段是私有(private)的。

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 的一部分之后仍然是借来的字段。

不应该只借那部分吗?有什么办法可以强制执行此操作吗?

最佳答案

你只能借用整个结构作为不可变或可变的,没有只借用它的一部分的概念。当这成为问题时,您可以使用 interior mutabilityRefCell 的形式:

pub struct EntityComponentSystem {
    entities: RefCell<HashMap<u64, Entity>>,
    entities_with_components: HashMap<TypeId, HashSet<u64>>,
}

现在您可以将整个结构作为不可变借用,并将 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
}

关于rust - 是否可以借用结构的一部分作为可变部分而其他部分作为不可变部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45858859/

相关文章:

rust - Rust 常量表达式可以使用 Default 之类的特性吗?

rust - 结构的可变性

rust - 从Rc <RefCell <T >>映射到Ref <'_,U>

reference - 为什么我可以返回对局部文字的引用而不是变量?

character-encoding - 将 ISO-8859-1/Latin-1 转换为字符串 (UTF-8) 有哪些选项?

rust - 使用hyper时如何直接控制http body(大尺寸)?

json - 如何将Serde与具有不同对象的JSON数组一起使用,以获取成功和错误?

rust - 使用actix-files提供静态文件时,如何设置 “expire”或 “Cache-Control” header ?

rust - 如何在不丢弃物体的情况下解构物体?

Rust 错误 [E0373] : closure may outlive the current function, 但它借用了 `iteration_index`