Несколько читателей ссылок и один автор ссылок в Rust - PullRequest
1 голос
/ 05 апреля 2020

В настоящее время я работаю над небольшой игрой на 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, или что-то еще?

1 Ответ

0 голосов
/ 06 апреля 2020

Вы правильно поняли, что вам, вероятно, понадобится использовать RefCell, или RwLock, или, возможно, даже R c. Однако эти понятия более продвинуты, и я не рекомендую пытаться использовать их, когда вы только начинаете изучать язык. Вместо этого я бы удалил ссылку на Корабль из структуры Игрока и просто дал бы Кораблю содержать ссылки на Игроков.

Если вы еще этого не сделали, я настоятельно рекомендую официальную книгу о ржавчине , отличное введение в язык с отличными примерами!

...