如何在Rust中的向量,切片或数组中交换项?

时间:2014-08-27 16:05:09

标签: 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这是可能的?

2 个答案:

答案 0 :(得分:23)

有一个swap method defined for &mut [T]。由于Vec<T>可以mutably dereferenced作为&mut [T],因此可以直接调用此方法:

fn main() {
    let mut numbers = vec![1, 2, 3];
    println!("before = {:?}", numbers);
    numbers.swap(0, 2);
    println!("after = {:?}", numbers);
}

要自己实现,必须编写一些不安全的代码。 Vec::swap is implemented喜欢这样:

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不允许从同一个向量中取两个可变借词。

答案 1 :(得分:2)

如@ gsingh2011所述,接受的答案不再是好方法。使用当前的Rust,这段代码工作正常:

fn main() {
    let mut numbers = vec![1, 2, 3];
    println!("before = {:?}", numbers);
    numbers.swap(0, 2);
    println!("after = {:?}", numbers);
}

try it here