Массивы (списки) в Rust 1.75: подробное руководство
Массивы (списки) в Rust
Что такое массив и зачем он нужен?
Представь, что ты собираешь коллекцию наклеек. Вместо того чтобы записывать каждую наклейку на отдельном листочке, ты можешь взять один альбом и сложить все наклейки в него по порядку. В программировании такой «альбом» называется массивом (или списком).
Массив — это контейнер, который хранит несколько значений одного типа подряд. Например, список чисел (количество порций супа), список названий фруктов или список высот, которые покорил альпинист.
В Rust есть два основных вида массивов: массив фиксированной длины (просто массив) и вектор (динамический список). Для начинающих удобнее всего использовать вектор — он может расти и уменьшаться, как настоящий список в твоей тетради.
Основной синтаксис
Создание массива (вектора)
Чтобы создать пустой список, используй Vec::new(). Если список уже есть, используй квадратные скобки и макрос vec!:
fn main() {
// Пустой список фруктов
let mut fruits: Vec<String> = Vec::new();
// Список с числами (количество порций супа)
let portions = vec![15, 20, 18, 22, 25];
println!("{:?}", portions); // [15, 20, 18, 22, 25]
}
Добавление элементов
Метод push добавляет элемент в конец списка. Обрати внимание на слово mut — оно означает, что список можно менять:
fn main() {
let mut fruits = Vec::new();
fruits.push("яблоко".to_string());
fruits.push("банан".to_string());
fruits.push("груша".to_string());
println!("{:?}", fruits); // ["яблоко", "банан", "груша"]
}
Доступ к элементам по индексу
Каждый элемент в списке стоит на своем месте — это индекс. Нумерация начинается с нуля! Первый элемент — индекс 0, второй — индекс 1 и так далее.
fn main() {
let portions = vec![15, 20, 18, 22, 25];
// Получаем первый элемент (индекс 0)
let first = portions[0];
println!("Первый день: {}", first); // 15
// Получаем третий элемент (индекс 2)
let third = portions[2];
println!("Третий день: {}", third); // 18
}
Изменение элемента
Чтобы изменить элемент, просто присвой новое значение по индексу:
fn main() {
let mut materials = vec![10, 5, 8, 3]; // количество хлеба, молока, масла, яиц
println!("Было: {:?}", materials);
// Удваиваем количество хлеба (второй элемент, индекс 1)
materials[1] = materials[1] * 2;
println!("Стало: {:?}", materials); // [10, 10, 8, 3]
}
Разбор типичных задач
Задача «Фрукты» (сбор списка)
Нужно собрать список фруктов, которые привозят каждый день. Используем цикл и ввод с клавиатуры:
use std::io;
fn main() {
let mut fruits: Vec<String> = Vec::new();
println!("Введи фрукты, которые привезли (по одному на строке).");
println!("Когда закончишь, напиши 'стоп'.");
loop {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Ошибка чтения");
let input = input.trim().to_string();
if input == "стоп" {
break;
}
fruits.push(input);
}
println!("Список всех фруктов за неделю:");
println!("{:?}", fruits);
}
Задача «Запас материалов» (изменение элемента)
Повар заметил ошибку: во втором пункте списка записано неправильное количество хлеба. Нужно его удвоить:
fn main() {
// Индекс 0: мука, индекс 1: хлеб, индекс 2: молоко
let mut storage = vec![12, 5, 8];
println!("До исправления: {:?}", storage);
// Удваиваем значение хлеба (индекс 1)
storage[1] = storage[1] * 2;
println!("После исправления: {:?}", storage);
}
Задача «Юный альпинист» (поиск по условию)
Нужно найти все высоты, которые больше 1000 метров:
fn main() {
let heights = vec![500, 1200, 800, 1500, 950, 1100];
println!("Высоты больше 1000 метров:");
for height in &heights {
if *height > 1000 {
println!("{}", height);
}
}
}
Частые ошибки новичков
- Забыть добавить mut — если ты хочешь менять список (добавлять, удалять, изменять элементы), обязательно пиши
let mut. Безmutсписок нельзя изменить. - Выход за границы массива — если в списке 5 элементов (индексы 0-4), а ты обращаешься к индексу 5, программа упадет с ошибкой. Всегда проверяй длину списка методом
.len(). - Путать массивы и векторы — в Rust есть массивы фиксированной длины (
[1, 2, 3]) и векторы (vec![1, 2, 3]). Для большинства задач используй векторы, они гибче. - Забыть to_string() — строки в Rust нужно явно преобразовывать. Если ты пишешь
"яблоко".to_string(), это правильно. Просто"яблоко"— это текст, а не строка.
Итоговый пример: «Робот-сортировщик»
На заводе робот сортирует детали. С конвейера поступают серийные номера. Нужно отобрать все детали с номерами, которые больше 100, и вывести их на экран.
use std::io;
fn main() {
let mut details: Vec<i32> = Vec::new();
println!("Введи серийные номера деталей (по одному на строке).");
println!("Для завершения введи 0.");
loop {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Ошибка чтения");
let number: i32 = input.trim().parse().expect("Ошибка! Введи число");
if number == 0 {
break;
}
details.push(number);
}
println!("Все детали: {:?}", details);
// Отбираем детали с номером больше 100
let mut selected: Vec<i32> = Vec::new();
for detail in &details {
if *detail > 100 {
selected.push(*detail);
}
}
println!("Детали для следующего этапа (номер > 100): {:?}", selected);
println!("Всего отобрано: {} деталей", selected.len());
}
Что дальше?
Массивы (списки) — это основа для хранения данных. Ты научился:
- Создавать списки
- Добавлять элементы
- Читать и изменять элементы по индексу
- Перебирать элементы в цикле
- Отбирать нужные элементы по условию
Попробуй решить задачи из этого раздела — они помогут закрепить навыки. Помни: практика — лучший способ научиться программировать!