我正在Rust中实现Nine Man's Morris的棋盘游戏。我有一个Game
结构,它拥有一个Board
结构。 Board
存储RefCell<HashSet>
个Position
结构的引用。 Board
和Game
共享生命周期参数。
pub struct Board<'a> {
pub positions: Vec<Position>,
pub ids_to_positions: HashMap<String, usize>,
p1_mills: RefCell<HashSet<(&'a Position, &'a Position, &'a Position)>>,
p2_mills: RefCell<HashSet<(&'a Position, &'a Position, &'a Position)>>,
can_mill: Cell<bool>,
}
pub struct Game<'a> {
pub board: Board<'a>,
pub player1: Player,
pub player2: Player,
current_player_id: i8,
}
Game::game_loop
循环通过一组方法(获取输入,更新棋盘等)直到游戏结束。这已经很好了,因为我已经添加了方法。
impl<'a> Game<'a> {
pub fn print(&self) {
self.board.print();
}
pub fn game_loop(&'a mut self) {
loop {
self.print();
self.make_move();
print!("can_mill: {}", self.board.can_mill());
self.board.update_mills(self.current_player_id);
self.switch_player();
}
}
pub fn make_move(&mut self) {}
pub fn switch_player(&self) {}
}
对self
的可变和不可变引用以及Board
上的2个引用有多种方法:
pub fn can_mill(&self) -> bool {}
pub fn update_mills(&'a self, player_id: i8) {}
update_mill
更新p1_mills
和p2_mills
字段,can_mill
引用can_mill
字段。
如果我删除了update_mills
中的game_loop
来电,则代码会进行编译。有了它,我得到了
无法借用
*self
作为可变对象,因为self.board
也是借用的 作为一成不变的。
我很确定这与该方法中的显式生命周期有关,但在我所有的阅读中,我无法让它工作或理解什么是无效的。这很令人困惑,因为没有我没有任何借贷错误。我也不清楚RefCell
中的磨机组是否破坏了任何东西(我实际上无法记住为什么它们首先存在于它们中)。
我意识到这很复杂,但我真的很感激一些帮助。我试图用一个更简单的例子重新创建这个问题,但不能遗憾。
答案 0 :(得分:0)
事实证明,我的问题确实是Why can't I store a value and a reference to that value in the same struct?的抽象版本。我认为使用RefCells
类解决了这个问题,但实际上只是抽象了远离我的问题。
删除了RefCells,删除了生命周期参数,并制作了一个Mill
结构,存储usizes
以便为Position
Vec
编制索引。