10

I'm trying to extract two elements from a Vec, which will always contain at least two elements. These two elements need to be extracted mutably as I need to be able to change values on both as part of a single operation.

Sample code:

struct Piece {
  x: u32,
  y: u32,
  name: &'static str
}

impl Piece {
  fn exec(&self, target: &mut Piece) {
    println!("{} -> {}", self.name, target.name)
  }
}

struct Board {
  pieces: Vec<Piece>
}

fn main() {
    let mut board = Board {
      pieces: vec![
        Piece{ x: 0, y: 0, name: "A" },
        Piece{ x: 1, y: 1, name: "B" }
      ]
    };

    let mut a = board.pieces.get_mut(0);
    let mut b = board.pieces.get_mut(1);
    a.exec(b);
}

At present, this fails to build with the following compiler errors:

piece.rs:26:17: 26:29 error: cannot borrow `board.pieces` as mutable more than once at a time
piece.rs:26     let mut b = board.pieces.get_mut(1);
                            ^~~~~~~~~~~~
piece.rs:25:17: 25:29 note: previous borrow of `board.pieces` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `board.pieces` until the borrow ends
piece.rs:25     let mut a = board.pieces.get_mut(0);
                            ^~~~~~~~~~~~
piece.rs:28:2: 28:2 note: previous borrow ends here
piece.rs:17 fn main() {
...
piece.rs:28 }

Unfortunately, I need to be able to obtain a mutable reference to both so that I can modify both within the Piece.exec method. Any ideas, or am I trying to do this the wrong way?

David Edmonds
  • 103
  • 2
  • 5

1 Answers1

10

Rust can't guarantee at compile time that get_mut is not going to mutably borrow the same element twice, so get_mut borrows the entire vector mutably.

Instead, use slices

pieces.as_slice().split_at_mut(1) is what you want to use here.

wimh
  • 15,072
  • 6
  • 47
  • 98
Manishearth
  • 14,882
  • 8
  • 59
  • 76