我在學習Rust,正如你所想象的那樣,借用檢查器是我最大的對手。所以這裏是我的設置,它是遊戲戰艦的一種箱子。遊戲基於Battlefield
結構,它由Cell
組成。 A Cell
可以引用Ship
,並且Ship
具有所引用的所有Cell
的向量,因此它是雙向只讀關係。滿足Rust借用檢查器與結構
pub struct Battlefield<'a> {
cells: Vec<Vec<Cell<'a>>>,
}
#[derive(Debug, PartialEq)]
pub struct Cell<'a> {
ship: Option<&'a Ship<'a>>
}
#[derive(Debug, PartialEq)]
pub struct Ship<'a> {
length: usize,
cells: Vec<&'a Cell<'a>>,
}
我的問題是Battlefield
的place_ship
功能:
impl<'a> Battlefield<'a> {
pub fn place_ship(&mut self,
ship: &'a mut Ship,
x: usize,
y: usize,
orientation: Orientation)
-> PlaceResult {
// check ship placement in bounds
// check affected cells are free
// set cells' ship ref to ship
// add cell refs to ship's cells field
}
}
這對我來說很有意義,我不認爲這裏有一個所有權的問題,但我錯了,看來:
#[cfg(test)]
mod tests {
use super::{Battlefield, X, Y};
use super::Orientation::*;
use super::super::ship::Ship;
#[test]
fn assert_ship_placement_only_in_bounds() {
let mut ship = Ship::new(3);
let mut bf = Battlefield::new();
assert_eq!(Ok(()), bf.place_ship(&mut ship, 0, 0, Horizontal));
assert_eq!(Ok(()), bf.place_ship(&mut ship, 5, 5, Vertical));
}
}
src/battlefield.rs:166:47: 166:51 error: cannot borrow `ship` as mutable more than once at a time [E0499]
src/battlefield.rs:166 assert_eq!(Ok(()), bf.place_ship(&mut ship, 5, 5, Vertical));
^~~~
src/battlefield.rs:165:47: 165:51 note: first mutable borrow occurs here
src/battlefield.rs:165 assert_eq!(Ok(()), bf.place_ship(&mut ship, 0, 0, Horizontal));
^~~~
我知道這只是一個簡短的摘錄,但整個代碼太多,張貼在這裏。 project can be found here(標準搭建'貨運')。
*但是整個代碼太多了,無法在這裏發佈* - 我**保證**,您可以使代碼小到足以在這裏發佈,同時仍然重現相同的錯誤。參見[MCVE]。 – Shepmaster
可能是http://stackoverflow.com/q/32300132/155423的副本;可能是http://stackoverflow.com/q/20698384/155423或http://stackoverflow.com/q/28833622/155423或http://stackoverflow.com/q/29893978/155423。或者有關可變別名的任何問題。 [就像錯誤說的](https://doc.rust-lang.org/error-index.html#E0499),你不能借用任何**任何可變多次一次。 – Shepmaster
「雙向」 - 「我不認爲存在所有權問題」 - 一旦您擁有雙向關係,總會遇到所有權問題。 –