Suppose that you have multiple stacks represented as vectors and you want to move data from one of the stacks to another. A convenient and "Rustic" way to do that is to use extend_from_slice
to extend one vector with a slice from the other vector without copying it, like this:
fn main() {
let mut s1 = vec![1, 2, 3];
let mut s2 = vec![];
println!("before #{}: {:?}", 1, s1);
println!("before #{}: {:?}", 2, s2);
s2.extend_from_slice(&s1[1..]);
s1.truncate(1);
println!("after #{}: {:?}", 1, s1);
println!("after #{}: {:?}", 2, s2);
}
This compiles fine and implements the move.
Now, if you want to support multiple vectors, even a variable number of them, you can store them as a vector of vectors, like this:
fn main() {
let mut stacks = vec![vec![1, 2, 3], vec![2, 3, 4], vec![]];
for (n, stack) in stacks.iter().enumerate() {
println!("before #{}: {:?}", n, stack);
}
stacks[2].extend_from_slice(&stacks[1][1..]);
stacks[1].truncate(1);
for (n, stack) in stacks.iter().enumerate() {
println!("after #{}: {:?}", n, stack);
}
}
However, if you try this trick to append a slice from one of the vectors to another, the borrow-checker will complain:
error[E0502]: cannot borrow `stacks` as immutable because it is also borrowed as mutable
--> examples/vector_vector_move.rs:10:34
|
10 | stacks[2].extend_from_slice(&stacks[1][1..]);
| ------ ----------------- ^^^^^^ immutable borrow occurs here
| | |
| | mutable borrow later used by call
| mutable borrow occurs here
Since the slice to move is from a different vector than the slice to extend, there should be no safety issues with performing the move. Rationale is that the "top-level" vector does not need to change size, it is only the inner vectors that need to change size.
Trying to split out the slice into a separate variable give the same error as before, and storing references to vectors instead of vectors directly gives a whole bunch of other errors saying similar things as above.
Is there a way to move a slice of a vector to another vector in a vector of vectors without creating a copy of the slice first?