2014-08-27 16 views
5

Il mio codice è simile al seguente:Come posso scambiare elementi in un vettore, una sezione o un array in Rust?

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

Rust è abbastanza sicuro io non sono autorizzato a "uscire di dereference" o "uscire di contenuto indicizzato", qualunque essa sia. Come faccio a convincere Rust che questo è possibile?

risposta

15

C'è un swap method defined for &mut [T]. Dal momento che un Vec<T> può essere mutably dereferenced come &mut [T], questo metodo può essere chiamato direttamente:

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

Per attuare da soli, è necessario scrivere del codice non sicuro. Vec::swap is implemented come questo:

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

Ci vogliono due puntatori prime dal vettore e usa ptr::swap per scambiare in modo sicuro.

C'è anche un mem::swap(&mut T, &mut T) quando è necessario scambiare due variabili distinte. Questo non può essere usato qui perché Rust non permetterà di prendere due mutuatari mutabili dallo stesso vettore.

2

Come accennato da @ gsingh2011, la risposta accettata non è più un buon approccio. Con Ruggine corrente di questo codice funziona bene:

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

try it here

+2

Ho aggiornato l'altra risposta, quindi questo è ormai superfluo. – Shepmaster

Problemi correlati