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/