В настоящее время я работаю над небольшой игрой на Rust, чтобы начать с языка, и в основном имею следующий код (здесь я написал только минимальный пример):
struct Player<'a> {
pub ship: &'a Ship<'a>,
}
impl<'a> Player<'a> {
pub fn run(&mut self) {
// Does some computing with self.ship.x/self.ship.y
}
}
struct Ship<'a> {
pub players: Vec<Player<'a>>,
pub x: f64,
pub y: f64,
}
impl<'a> Ship<'a> {
pub fn add_player(&mut self, player: Player<'a>) {
self.players.push(player);
}
}
fn main() {
let mut ship = Ship {
players: vec![],
x: 0.0,
y: 0.0,
};
// At some point create a player for the ship
let player = Player { ship: &ship };
ship.add_player(player); // <- Forbidden
}
Самое важное здесь заключается в том, что все Player
имеют доступ к кораблю, к которому они принадлежат, с неизменной ссылкой, так что они легко имеют доступ к положению (x / y) своего корабля (которое меняется со временем по ходу игры). Однако этот код не компилируется:
error[E0502]: cannot borrow `ship` as mutable because it is also borrowed as immutable
--> src/main.rs:32:5
|
31 | let player = Player { ship: &ship };
| ----- immutable borrow occurs here
32 | ship.add_player(player);
| ^^^^^----------^^^^^^^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
Я понимаю, что player
заимствует ship
как неизменный и что я все еще пытаюсь изменить ship
после того, как заимствование произойдет, но я Не можете найти правильный смарт-указатель или оболочку, которую я должен использовать для такого рода случаев? Вы бы использовали RwLock
, или RefCell
, или что-то еще?