Игровой цикл в Rust при удовлетворении проверки заимствования

Вот очень простой пример игрового цикла в Rust:

trait Entity {
    fn update(&mut self, world: &mut World);
}

struct World {
    entities: Vec<Box<Entity>>
}
impl World {
    fn update(&mut self) {
        for ent in self.entities.iter_mut() {
            ent.update(self);
        }
    }
}

Однако это не работает:

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> test.rs:12:16
   |
11 |                    for ent in self.entities.iter_mut() {
   |                               ------------- first mutable borrow occurs here
12 |                            ent.update(self);
   |                                ^^^^ second mutable borrow occurs here
13 |                    }
   |                    - first borrow ends here

error: aborting due to previous error

Чтобы получить объект из вектора, мне нужно сделать изменяемое заимствование структуры World, что не позволит объекту использовать его каким-либо образом.

Что было бы хорошим способом структурировать это, чтобы я мог как мутировать сущность, так и иметь ссылку на другие объекты в мире (для проверки столкновений и т. д.)?

Единственный способ, который я могу придумать, - это либо заставить сущность возвращать обновленную копию себя (я не думаю, что все это выделение и копирование будет хорошо для производительности), либо использовать unsafe.


person Colonel Thirty Two    schedule 28.02.2017    source источник
comment
Можно ли разделить Мир на две части, entities и все остальное? Если вы раздадите весь мир, получатель может изменить entities и, таким образом, сделать цикл недействительным.   -  person kennytm    schedule 28.02.2017
comment
@kennytm Ну, обновляемая сущность должна иметь возможность изменять существующие сущности (например, сущность пули должна изменить здоровье игрока). Похоже, что лучший способ по ссылке Фрэнсиса - использовать RefCell для объектов в массиве.   -  person Colonel Thirty Two    schedule 28.02.2017