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/