我不知道如何使以下代码成功编译。第一步是努力克服生命周期注释,但是,我认为它终于解决了。
下一步是HashMap
条目周围的借用和生存期。我觉得我已经对兔子洞太深了,需要一些指导才能离开。
use std::collections::HashMap;
struct Player {
id: u32,
}
struct Game<'a> {
black: &'a Player,
white: &'a Player,
win: bool,
timestamp: u32,
}
struct Base<'b> {
games: &'b mut Vec<Game<'b>>,
players: &'b mut HashMap<u32, Player>,
}
impl<'c> Base<'c> {
fn create_game(self, black_id: u32, white_id: u32, win: bool, timestamp: u32) -> &'c Game<'c> {
let black_player = self
.players
.entry(black_id)
.or_insert(Player { id: black_id });
let white_player = self
.players
.entry(white_id)
.or_insert(Player { id: white_id });
let game = Game {
black: &black_player,
white: &white_player,
win: win,
timestamp: timestamp,
};
self.games.push(game);
&self.games[0]
}
}
error[E0499]: cannot borrow `*self.players` as mutable more than once at a time
--> src/lib.rs:25:28
|
19 | impl<'c> Base<'c> {
| -- lifetime `'c` defined here
20 | fn create_game(self, black_id: u32, white_id: u32, win: bool, timestamp: u32) -> &'c Game<'c> {
21 | let black_player = self
| ____________________________-
| |____________________________|
| ||
22 | || .players
| ||____________________- first mutable borrow occurs here
23 | | .entry(black_id)
| |_____________________________- argument requires that `*self.players` is borrowed for `'c`
24 | .or_insert(Player { id: black_id });
25 | let white_player = self
| _____________________________^
26 | | .players
| |_____________________^ second mutable borrow occurs here
error[E0597]: `black_player` does not live long enough
--> src/lib.rs:31:20
|
19 | impl<'c> Base<'c> {
| -- lifetime `'c` defined here
...
31 | black: &black_player,
| ^^^^^^^^^^^^^ borrowed value does not live long enough
...
37 | self.games.push(game);
| --------------------- argument requires that `black_player` is borrowed for `'c`
38 | &self.games[0]
39 | }
| - `black_player` dropped here while still borrowed
error[E0597]: `white_player` does not live long enough
--> src/lib.rs:32:20
|
19 | impl<'c> Base<'c> {
| -- lifetime `'c` defined here
...
32 | white: &white_player,
| ^^^^^^^^^^^^^ borrowed value does not live long enough
...
37 | self.games.push(game);
| --------------------- argument requires that `white_player` is borrowed for `'c`
38 | &self.games[0]
39 | }
| - `white_player` dropped here while still borrowed
[如果您只想使代码“编译”(某种意义上说“可用于进一步开发”),而不是尝试“学习如何在Rust中完成复杂的生命周期”,那么我建议以下代码的简单版本。
#[derive(Copy, Clone)]
struct Player {
id: u32,
}
#[derive(Copy, Clone)]
struct Game {
black: Player,
white: Player,
win: bool,
timestamp: u32
}
struct Base {
games: Vec<Game>,
players: HashMap<u32, Player>
}
impl Base {
fn create_game(&mut self, black_id: u32, white_id: u32, win: bool, timestamp: u32) -> Game {
self.players.entry(black_id).or_insert(Player {id: black_id });
self.players.entry(white_id).or_insert(Player {id: white_id });
let black_player: &Player = self.players.get(&black_id).unwrap(); // Should be safe to unwrap here
let white_player: &Player = self.players.get(&white_id).unwrap(); // Should be safe to unwrap here
let game = Game {
black: *black_player,
white: *white_player,
win: win,
timestamp: timestamp
};
self.games.push(game);
self.games[0]
}
}