-1

I'm going to switch elements in a Vec, but my solution has ownership problem, Is my code totally wrong?

Given [1, 2, 3, 4, 5, 6], the expected output is [4, 5, 6, 1, 2, 3].

fn switch(nums: &mut Vec<i32>, k: i32) {

    let t = k as usize;
    let v1 = &nums[..t];
    nums.drain(t..);
    nums.extend_from_slice(v1);

}
error[E0502]: cannot borrow `*nums` as mutable because it is also borrowed as immutable
 --> src/main.rs:7:5
  |
6 |     let v1 = &nums[..t];
  |               ---- immutable borrow occurs here
7 |     nums.extend_from_slice(v1);
  |     ^^^^^-----------------^^^^
  |     |    |
  |     |    immutable borrow later used by call
  |     mutable borrow occurs here
E_net4
  • 27,810
  • 13
  • 101
  • 139
Zij.Fang
  • 21
  • 7

1 Answers1

2

Use either rotate_left or rotate_right, where mid is the middle of the vector. This will effectively perform the intended switch.

let x = vec![1, 2, 3, 4, 5, 6];
let mid = x.len() / 2;

With rotate_left:

x.rotate_left(mid);
assert_eq!(&x, &[4, 5, 6, 1, 2, 3]);

With rotate_right:

x.rotate_right(mid);
assert_eq!(&x, &[4, 5, 6, 1, 2, 3]);

The same methods are available for plain mutable slices. In the event that the two partitions to swap have the same size but are not contiguous, one can create two iterators of mutable elements and swap them, either using swap_with_slice...

let (left, right) = x.split_at_mut(mid);
left.swap_with_slice(right);

... or by swapping each element one by one.

let (left, right) = x.split_at_mut(mid);
for (l, r) in Iterator::zip(left.iter_mut(), right.iter_mut()) {
    std::mem::swap(l, r);
}
assert_eq!(&x, &[4, 5, 6, 1, 2, 3]);

See also:

E_net4
  • 27,810
  • 13
  • 101
  • 139