Vec
Vec — стандартный расширяемый буфер в куче:
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
fn main() {
let mut v1 = Vec::new();
v1.push(42);
println!("v1: len = {}, capacity = {}", v1.len(), v1.capacity());
let mut v2 = Vec::with_capacity(v1.len() + 1);
v2.extend(v1.iter());
v2.push(9999);
println!("v2: len = {}, capacity = {}", v2.len(), v2.capacity());
// Канонический макрос для инициализации вектора элементами.
let mut v3 = vec![0, 0, 1, 2, 3, 4];
// Оставить только чётные элементы.
v3.retain(|x| x % 2 == 0);
println!("{v3:?}");
// Удалить подряд идущие дубликаты.
v3.dedup();
println!("{v3:?}");
}
Vec реализует Deref<Target = [T]>, что означает, что на Vec можно вызывать методы срезов.
This slide should take about 5 minutes.
Vec— один из видов коллекций, наряду сStringиHashMap. Содержащиеся в нём данные хранятся в куче. Это значит, что объём данных не нужно знать во время компиляции: он может расти или уменьшаться во время выполнения.- Обратите внимание, что
Vec<T>тоже обобщённый тип, ноTуказывать явно не нужно. Как всегда в выводе типов Rust,Tопределился при первом вызовеpush. vec![...]— канонический макрос, который используют вместоVec::new(); он позволяет сразу добавить элементы в вектор.- Для индексации вектора используются
[], но при выходе за границы они вызовут панику. АльтернативноgetвернётOption. Функцияpopудаляет последний элемент. - Студенты могут спросить, почему у
Vecи срезов так много собственных методов, а стандартная библиотека не предоставляет трейты-контейнеры. Основная причина такого дизайна в том, что Rust вместо этого централизует функциональность в трейтеIterator, который абстрагирует и потоки ввода-вывода, и коллекции, при этом избегая материализации промежуточных коллекций.