Вектор - множество данных одного типа, количество которых можно изменять: добавлять и удалять элементы. Нужен, когда:
требуется собрать набор элементов для обработки в других местах;
нужно выставить элементы в определённом порядке, с добавлением новых элементов в конец;
нужно реализовать стэк;
нужен массив изменяемой величины и расположенный в куче.
Методы
// Задание пустого вектора:
// let mut a test_vector: Vec<i32> = Vec::new();
// Задание вектора со значениями через макрос:
letmuttest_vector=vec![1,2,3,4];test_vector.push(42);// добавить число 42 в конец mut вектора
letSome(last)=test_vector.pop();// удаляет и возвращает последний элемент (возвращает Option<T>)
test_vector.remove(0);// удалить первый элемент =1
foriin&muttest_vector{// пройти вектор как итератор для вывода
*i+=1;// изменять значения при их получении требует делать '*' dereference
println!("{i}");}println!("Vector length: {}",test_vector.len());// количество элементов
Элемент можно получить либо с помощью индекса, либо с помощью безопасного метода get:
letmuttest_vector=vec![1,2,3,4,5];println!("Third element of vector is: {}",&test_vector[2]);// индекс
letthird: Option<&i32>=test_vector.get(2);// безопасный метод get
matchthird{Some(third)=>println!("Third element of vector is: {}",third),None=>println!("There is no third element")}
Разница в способах в реакции на попытку взять несуществующий элемент за пределами вектора. Взятие через индекс приведёт к панике и остановке программы. Взятие с помощью get сопровождается проверкой и обработкой ошибки.
Удаление элемента
Метод .remove(index):
letmutnumbers=vec![1,2,3,4];numbers.remove(1);// удаляет элемент с индексом 1
println!("{:?}",numbers);// [1, 3, 4]
.remove() сдвигает все последующие элементы, что может быть дорого для больших векторов (O(n));
Возвращает удалённый элемент;
Требует mut, так как изменяет вектор;
Индекс должен быть в пределах длины, иначе паника.
Хранение элементов разных типов в векторе
Rust нужно заранее знать при компиляции, сколько нужно выделять памяти под каждый элемент. Если известны заранее все типы для хранения, то можно использовать промежуточный enum:
Смена элементов при сравнении, метод .sort_by() принимает замыкание (closure) для пользовательской сортировки:
number_vector.sort_by(|a,b|b.cmp(a));
|a, b| — это замыкание;
b.cmp(a) возвращает порядок: Ordering::Less, Equal или Greater. Инверсия (b.cmp(a) вместо a.cmp(b)) даёт убывающий порядок.
Альтернатива: .sort_by_key() для сортировки по вычисляемому ключу:
letmutnumbers=vec![3,1,4,1,5];numbers.sort_by_key(|&x|-x);// по убыванию через отрицание
println!("{:?}",numbers);// [5, 4, 3, 1, 1]
Если вернуть Reverse со ссылкой и без *, это приведёт к проблеме с временем жизни.
Сортировка вектора по ключу
usestd::collections::HashSet;fnmain(){letmutvowels=HashSet::new();vowels.insert('e');vowels.insert('a');vowels.insert('i');vowels.insert('o');vowels.insert('u');// Конвертация в Vec и сортировка
letmutvowel_vec: Vec<char>=vowels.into_iter().collect();// Свой порядок сортировки: a, e, i, o, u
letvowel_order=|c: &char|matchc{'a'=>0,'e'=>1,'i'=>2,'o'=>3,'u'=>4,_=>5,};vowel_vec.sort_by_key(vowel_order);println!("Sorted vowels: {:?}",vowel_vec);// ['a', 'e', 'i', 'o', 'u']
}
Дедупликация вектора
Удаление одинаковых элементов в векторе, похоже на работу с HashSet.
lets="aabbccdddeeeeffffeee";letmutchars: Vec<char>=s.chars().collect();// Сначала отсортировать, чтобы собрать одинаковые элементы вместе
chars.sort_unstable();// dedup() удаляет на месте одинаковые СТОЯЩИЕ РЯДОМ в векторе элементы
chars.dedup();// собрать назад в String:
letunique_s: String=chars.into_iter().collect();