rust - 如何同时获取对两个数组元素的可变引用?

标签 rust

fn change(a: &mut i32, b: &mut i32) {
    let c = *a;
    *a = *b;
    *b = c;
}

fn main() {
    let mut v = vec![1, 2, 3];
    change(&mut v[0], &mut v[1]);
}

当我编译上面的代码时,出现错误:

error[E0499]: cannot borrow `v` as mutable more than once at a time
 --> src/main.rs:9:32
  |
9 |         change(&mut v[0], &mut v[1]);
  |                     -          ^   - first borrow ends here
  |                     |          |
  |                     |          second mutable borrow occurs here
  |                     first mutable borrow occurs here

为什么编译器禁止呢? v[0]v[1] 占用不同的内存位置,因此将它们一起使用并不危险。遇到这个问题怎么办?

最佳答案

你可以用 split_at_mut() 解决这个问题:

let mut v = vec![1, 2, 3];
let (a, b) = v.split_at_mut(1);   // Returns (&mut [1], &mut [2, 3])
change(&mut a[0], &mut b[0]); 

不幸的是,编译器还不能识别出无数安全的事情。 split_at_mut() 就是这样,一个在内部使用 unsafe block 实现的安全抽象。

对于这个问题,我们也可以这样做。以下是我在代码中使用的内容,无论如何我都需要将所有三种情况分开(I:索引越界,II:索引相等,III:单独的索引)。

enum Pair<T> {
    Both(T, T),
    One(T),
    None,
}

fn index_twice<T>(slc: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
    if a == b {
        slc.get_mut(a).map_or(Pair::None, Pair::One)
    } else {
        if a >= slc.len() || b >= slc.len() {
            Pair::None
        } else {
            // safe because a, b are in bounds and distinct
            unsafe {
                let ar = &mut *(slc.get_unchecked_mut(a) as *mut _);
                let br = &mut *(slc.get_unchecked_mut(b) as *mut _);
                Pair::Both(ar, br)
            }
        }
    }
}

关于rust - 如何同时获取对两个数组元素的可变引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42346686/

相关文章:

rust - 库箱中多个可执行文件的文件布局

rust - 我可以用借用的元素来改变向量吗?

algorithm - 获取 BTreeMap 中最大值的键的惯用方法?

rust - 我如何表示可以是 Rc<T> 或 Weak<T> 的字段

rust - 在 Gitlab CI 中缓存 Rust/Wasm 工具?

data-structures - 如何从 cons 列表中弹出一个值?

generics - 返回通用 lambda 时为 "Ambiguous associated type"

macros - 如何在宏中导入类型?

rust - 如果我已经实现了 Drop,为什么使用 PhantomData 通知编译器结构拥有泛型很有用?

windows - 无法在 Windows 上使用 Rust 和 GTK 运行 pkg-config