我的代码看起来像这样:
fn swap<T>(mut collection: Vec<T>, a: usize, b: usize) {
let temp = collection[a];
collection[a] = collection[b];
collection[b] = temp;
}
Rust相信我无法“移动解除引用”或“移动索引内容”,不管那是什么意思。我该如何说服Rust这是可能的?
我的代码看起来像这样:
fn swap<T>(mut collection: Vec<T>, a: usize, b: usize) {
let temp = collection[a];
collection[a] = collection[b];
collection[b] = temp;
}
Rust相信我无法“移动解除引用”或“移动索引内容”,不管那是什么意思。我该如何说服Rust这是可能的?
有一个为&mut [T]
定义的swap
方法。由于Vec<T>
可以被可变地解引用为&mut [T]
,因此可以直接调用此方法:
fn main() {
let mut numbers = vec![1, 2, 3];
println!("before = {:?}", numbers);
numbers.swap(0, 2);
println!("after = {:?}", numbers);
}
Vec::swap
的实现如下所示:fn swap(&mut self, a: usize, b: usize) {
unsafe {
// Can't take two mutable loans from one vector, so instead just cast
// them to their raw pointers to do the swap
let pa: *mut T = &mut self[a];
let pb: *mut T = &mut self[b];
ptr::swap(pa, pb);
}
}
这段代码从向量中获取了两个裸指针,并使用 ptr::swap
安全地交换它们。
当你需要交换两个不同的变量时,也可以使用 mem::swap(&mut T, &mut T)
。但是在这里无法使用,因为 Rust 不允许从同一个向量中取出两个可变借用。
正如 @gsingh2011 所提到的,被接受的答案已经不再是一个好方法。使用当前版本的 Rust,这段代码可以正常工作:
fn main() {
let mut numbers = vec![1, 2, 3];
println!("before = {:?}", numbers);
numbers.swap(0, 2);
println!("after = {:?}", numbers);
}