2014-08-27 1 views
5

Мой код выглядит следующим образом:Как я могу поменять элементы в векторе, разрезе или массиве в Rust?

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

Rust довольно уверен, что я не позволил «выйти из разыменования» или «выйти из индексированного контента», что бы это ни есть. Как убедить Руста, что это возможно?

ответ

15

Существует 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 не позволит брать два измененных заимства из одного и того же вектора.

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

+2

Я обновил другой ответ, так что теперь это излишним. – Shepmaster

 Смежные вопросы

  • Нет связанных вопросов^_^