Хотя это не подходит и эффективно использовать регулярные выражения для этой цели, иногда регулярные выражения предоставляют быстрые решения для простых проблем совпадения, и, на мой взгляд, не так уж и сложно использовать регулярные выражения для тривиальных работ.
Существует окончательное сообщение в блоге о совпадении сокровенных HTML-элементов, написанных Стивеном Левитаном.
Вы не можете сделать две изменяемые ссылки на одни и те же данные. Это явно запрещается средством проверки заимствований, чтобы предотвратить одновременные изменения. Однако вы можете обойти проверку чеков с помощью блоков unsafe
.
Хотя в вашем случае v[0]
и v[1]
явно являются отдельными кусками, это не выдерживает серьезного внимания. Что, если v
- это какая-то карта, называемая NullMap
, которая отображает все элементы в одно поле? Как известно компилятору в Vec
операциях v[0];v[1];
безопасно, но в NullMap
нет?
Если вы пытаетесь поменять два элемента массива, почему бы не пойти slice::swap
?
fn main() {
let mut v = vec![1, 2, 3];
v.swap(0,1);
println!("{:?}",v);
}
Также v
должен быть mut
, потому что вы меняете вектор. Неизменяемая версия будет клонировать и выполнять обмен на нее.
Метод [T]::iter_mut()
возвращает итератор, который может дать изменяемую ссылку для каждого элемента в срезе. Другие коллекции также имеют метод iter_mut
. Эти методы часто инкапсулируют небезопасный код, но их интерфейс полностью безопасен.
Вот черта расширения общего назначения, которая добавляет метод на срезах, который возвращает изменчивые ссылки на два разных элемента по индексу:
pub trait SliceExt {
type Item;
fn get_two_mut(&mut self, index0: usize, index1: usize) -> (&mut Self::Item, &mut Self::Item);
}
impl<T> SliceExt for [T] {
type Item = T;
fn get_two_mut(&mut self, index0: usize, index1: usize) -> (&mut Self::Item, &mut Self::Item) {
match index0.cmp(&index1) {
Ordering::Less => {
let mut iter = self.iter_mut();
let item0 = iter.nth(index0).unwrap();
let item1 = iter.nth(index1 - index0 - 1).unwrap();
(item0, item1)
}
Ordering::Equal => panic!("[T]::get_two_mut(): received same index twice ({})", index0),
Ordering::Greater => {
let mut iter = self.iter_mut();
let item1 = iter.nth(index1).unwrap();
let item0 = iter.nth(index0 - index1 - 1).unwrap();
(item0, item1)
}
}
}
}
Проблема заключается в том, что &mut v[…]
сначала с мутностью заимствует v
, а затем передает переменную ссылку на элемент на функцию изменения.
Этот комментарий reddit имеет решение вашей проблемы.
Редактировать: Спасибо за хедз-ап, Shepmaster. par-vec - это библиотека, которая позволяет с легкостью брать раздельные разделы vec.
На ночном канале сопоставление образцов может выполняться с помощью срезов. Вы можете использовать это, если у вас нет огромных индексов, и ваши индексы известны во время компиляции.
#![feature(slice_patterns)]
fn change(a: &mut i32, b: &mut i32) {
let c = *a;
*a = *b;
*b = c;
}
fn main() {
let mut arr = [5, 6, 7, 8];
{
let &mut [ref mut a, _, ref mut b, _..] = &mut arr;
change(a, b);
}
assert_eq!(arr, [7, 6, 5, 8]);
}
Обратите внимание, что вам нужно включить функцию slice_patterns
.