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

10 rust

我的代码看起来像这样:

fn swap<T>(mut collection: Vec<T>, a: usize, b: usize) {
    let temp = collection[a];
    collection[a] = collection[b];
    collection[b] = temp;
}
Run Code Online (Sandbox Code Playgroud)

Rust非常肯定我不允许"脱离引用"或"移出索引内容",不管是什么.我如何说服Rust这是可能的?

Arj*_*jan 24

有一种swap方法定义&mut [T].由于a Vec<T>可以作为a 可变地解除引用&mut [T],因此可以直接调用此方法:

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

要自己实现,必须编写一些不安全的代码.像这样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);
    }
}
Run Code Online (Sandbox Code Playgroud)

它需要两个来自向量的原始指针并用于ptr::swap安全地交换它们.

mem::swap(&mut T, &mut T)需要交换两个不同的变量.这不能在这里使用,因为Rust不允许从同一个向量中取两个可变的借位.


Ale*_*lar 6

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

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

在这里试试

  • 我已经更新了另一个答案,所以这现在是多余的。 (3认同)