rust - 如何在不冲突借用的情况下切换向量的两个部分?

标签 rust borrow-checker

我打算在 Vec 中切换元素,但我的解决方案存在所有权问题,我的代码是否完全错误?

给定 [1, 2, 3, 4, 5, 6],预期输出为 [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

最佳答案

使用 rotate_leftrotate_right ,其中 mid 是向量的中间。这将有效地执行预期的切换。

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

使用rotate_left:

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

使用rotate_right:

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

相同的方法可用于普通可变切片。如果要交换的两个分区大小相同但不连续,可以创建两个可变元素的迭代器并交换它们,使用 swap_with_slice ...

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

... 或者通过一个一个地交换每个元素。

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]);

另见:

关于rust - 如何在不冲突借用的情况下切换向量的两个部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56700889/

相关文章:

parsing - 将闭包作为参数并返回值,Fn或FnMut是否更惯用?

image - 如何对 Rust Piston 图像进行编码并在内存中获取结果?

rust - Actix-web : send message to db handler, 有条件地向第二个处理程序发送消息

rust - 阐明在函数签名中将两个对不同范围的引用对象的引用绑定(bind)到相同生命周期的含义

rust - 两个可变借用发生在同一条线上?

rust - 如何引用可变切片

rust - 不匹配的 ARM 是否会在 Rust 的 "match"语句中获取变量的所有者?

rust - Rust的确切自动引用规则是什么?

Rust 借用检查器仅在返回具有相同生命周期的引用的函数时多次提示借用是可变的

pointers - 当所属变量不可变时,如何插入析构函数调用 `fn drop(&mut self)` 调用?