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块实现的安全抽象。

对于这个问题,我们也可以这样做。以下是我在代码中使用的一些东西,无论如何我都需要将所有三种情况分开(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/61980224/

相关文章:

rust - 检查 X 是否是 Y 的倍数,其中 Y 可能为零

rust - 从借用它的循环内部操作对象

rust - 尝试为结构设置带有生存期的返回值时,由于需求冲突,因此无法为autoref推断适当的生存期

rust - 如何使用 Rust 跟踪获取/存储跨度持续时间?

rust - 编译器运行有某种顺序吗?

error-handling - 为什么在扩展失败类型的结果时得到 "the method exists but the following trait bounds were not satisfied"?

c++ - 静态链接启用了PIC的内置库时,链接器PIC错误

rust - 如何解析 'Vec<Peekable<dyn Iterator<Item = T>>> doesn' t 的大小在编译时已知?

arrays - Rust中的意外行为 “for in n..m”

rust - 为什么在使用特征时参数类型必须是 'static