2014-08-27 12 views
5

Mã của tôi trông như thế này:Làm cách nào để trao đổi các mục trong một vectơ, slice hoặc mảng trong Rust?

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

Rust là khá chắc chắn tôi không được phép để "di chuyển ra khỏi dereference" hoặc "di chuyển ra khỏi nội dung được lập chỉ mục", bất kể đó là. Làm thế nào để thuyết phục Rust rằng điều này là có thể?

Trả lời

15

Có một số swap method defined for &mut [T]. Kể từ khi một Vec<T> có thể mutably dereferenced như một &mut [T], phương pháp này có thể được gọi trực tiếp:

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

Để thực hiện điều này cho mình, bạn phải viết một số mã không an toàn. Vec::swap is implemented như thế này:

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); 
    } 
} 

Phải mất hai con trỏ thô từ các vector và sử dụng ptr::swap để trao đổi chúng một cách an toàn.

Ngoài ra còn có mem::swap(&mut T, &mut T) khi bạn cần trao đổi hai biến riêng biệt. Điều đó không thể được sử dụng ở đây vì Rust sẽ không cho phép lấy hai khoản vay có thể thay đổi từ cùng một véc tơ.

2

Như đã đề cập trong @ gsingh2011, câu trả lời được chấp nhận không còn là cách tiếp cận tốt nữa. Với Rust hiện tại mã này hoạt động tốt:

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

try it here

+2

Tôi đã cập nhật câu trả lời khác, vì vậy đây là hiện nay không cần thiết. – Shepmaster

Các vấn đề liên quan