Как поменять местами элементы массива?
Я хочу поменять местами элементы slice data
использование функции библиотеки, но она не работает из-за нескольких заимствований:
mem::swap(&mut data[i], &mut data[j]); //error
Это можно сделать вручную, как обычно:
let temp = data[i];
data[i] = data[j];
data[j] = temp;
но я не думаю, что использование этого кода каждый раз здорово. Есть ли другое решение для использования библиотеки swap для срезов обычно?
1 ответов
здесь swap
метод на ломтики: data.swap(i, j)
.
исходный код не работает, потому что язык требует, чтобы &mut
s не псевдоним, то есть, если часть данных доступна через &mut
, тогда не должно быть другого способа использовать эти данные. В общем, для последовательных индексов data[i]
, data[j]
компилятор не может гарантировать, что i
и j
разные. Если они одинаковы, то индексирование относится к одной и той же памяти и поэтому &mut data[i]
и &mut data[j]
будет два указателя на одни и те же данные: незаконно!
.swap
использует немного unsafe
код внутри, не забудьте обработать i == j
дело правильно, избегая сглаживания &mut
указатели. Тем не менее, это не есть использовать unsafe
, только для того, чтобы эта "примитивная" операция была высокопроизводительной (и я определенно мог представить будущие улучшения языка / библиотеки, которые уменьшают необходимость в небезопасном здесь, делая требование инварианты проще выразить), например, следующая безопасная реализация:
use std::cmp::Ordering;
use std::mem;
fn swap<T>(x: &mut [T], i: usize, j: usize) {
let (lo, hi) = match i.cmp(&j) {
// no swapping necessary
Ordering::Equal => return,
// get the smallest and largest of the two indices
Ordering::Less => (i, j),
Ordering::Greater => (j, i),
};
let (init, tail) = x.split_at_mut(hi);
mem::swap(&mut init[lo], &mut tail[0]);
}
ключ здесь split_at_mut
который разделяет срез на две непересекающиеся половины (это делается с помощью unsafe
внутренне, но стандартная библиотека Rust построена на unsafe
: язык предоставляет "примитивные" функции, а библиотеки строят остальные поверх них).