Перейти к содержанию

Векторы Rust

Posted on:10 мая 2023 г. at 13:17

Example Dynamic OG Image link В этой статье мы подробно рассмотрим векторы Rust, мощную и гибкую структуру данных для работы с массивами с изменяемым размером. На примерах, начиная от базовых и заканчивая продвинутыми, мы стремимся помочь вам получить полное представление об этой важной функции Rust.

Что такое векторы?

Векторы в Rust аналогичны динамическим массивам или ArrayList на других языках. Они могут расти или уменьшаться в размере и хранить элементы одного типа. Векторы являются частью стандартной библиотеки Rust и представлены типом Vec<T>, где T - тип элементов в векторе.

Создание векторов

Создание вектора в Rust несложно. Можно создать пустой вектор или инициализировать его с помощью элементов.

// Создание пустого вектора
let mut numbers: Vec<i32> = Vec::new();

// Создание вектора с элементами
let numbers = vec![1, 2, 3, 4, 5];

Емкость и перераспределение

Векторы в Rust хранят свои элементы в куче. Они имеют емкость, которая указывает объем пространства, выделенного для элементов. При добавлении элементов к вектору и превышении его емкости Rust автоматически увеличивает вектор, перераспределяя память, удваивая емкость каждый раз.

let mut numbers = Vec::with_capacity(2);
numbers.push(1);
numbers.push(2);
println!("Вместительность: {}", numbers.capacity()); // Вместительность: 2

// Эта операция инициирует перераспределение
numbers.push(3);
println!("Вместительность: {}", numbers.capacity()); // Вместительность: 4

Добавление и удаление элементов

Можно легко добавлять и удалять элементы из вектора с помощью методов push, pop, insert и remove.

let mut numbers = vec![1, 2, 3];
numbers.push(4);
numbers.push(5);
println!("{:?}", numbers); // [1, 2, 3, 4, 5]

let last = numbers.pop();
println!("Удаленный: {:?}", last); // Удаленный: Some(5)
println!("{:?}", numbers); // [1, 2, 3, 4]

numbers.insert(1, 42);
println!("{:?}", numbers); // [1, 42, 2, 3, 4]

let removed = numbers.remove(1);
println!("Удаленный: {}", removed); // Удаленный: 42
println!("{:?}", numbers); // [1, 2, 3, 4]

Доступ к элементам и их изменение

Доступ к элементам вектора можно осуществлять с помощью индекса метода get или сопоставления шаблонов. Модификация элементов также возможна с изменяемыми ссылками.

let mut numbers = vec![1, 2, 3, 4, 5];

// Доступ к элементам по индексу
println!("Первый элемент: {}", numbers[0]); // Первый элемент: 1

// Доступ к элементам с помощью метода `get`
let third = numbers.get(2);
println!("Третий элемент: {:?}", third); // Третий элемент: Some(3)

match numbers.get(2) {
    Some(val) => println!("Третий элемент: {}", val),
    None => println!("Элемент не найден"),
}

//Изменение элементов
numbers[1] = 42;
println!("{:?}", numbers); // [1, 42, 3, 4, 5]

Итерация по вектору

Можно выполнить итерацию по вектору с помощью цикла for, который позволяет выполнять операции над каждым элементом.

let numbers = vec![1,2, 3, 4, 5];
// Итерация по векторным элементам
for num in &numbers {
  println!("Number: {}", num);
}

// Итерация по изменяемым ссылкам для изменения векторных элементов
let mut numbers = vec![1, 2, 3, 4, 5];
for num in &mut numbers {
  *num *= 2;
}
println!("{:?}", numbers); // [2, 4, 6, 8, 10]

Срез векторов

Фрагментирование элементов допускается в векторе. Для создания фрагмента можно использовать синтаксис диапазона.

let numbers = vec![1, 2, 3, 4, 5];

// Создание фрагмента из индекса 1 (включительно) в 4 (эксклюзивно)
let slice = &numbers[1..4];
println!("{:?}", slice); // [2, 3, 4]

Помните, что синтаксис диапазона является полуоткрытым, что означает, что конечный индекс является эксклюзивным. Если требуется включить последний элемент, необходимо использовать диапазон 1..=4.

Создание векторов из итераторов

Можно создать вектор из любого итератора, который вырабатывает элементы одного типа с помощью метода collect.

// Создание вектора квадратных чисел
let numbers = vec![1, 2, 3, 4, 5];
let squared: Vec<i32> = numbers.iter().map(|n| n * n).collect();
println!("{:?}", squared); // [1, 4, 9, 16, 25]

Дополнительные операции с вектором

Существует много других полезных методов, доступных для векторов, таких как len, is_empty, contains, retain, sort и concat. Полный список можно найти в официальной документации по Rust.

К настоящему времени у вас должно сложиться четкое понимание векторов Rust и способов эффективной работы с ними. От создания и изменения векторов до итерации и разрезания, эти мощные структуры данных предлагают широкий спектр возможностей для управления динамическими массивами в Rust.