Rust: с нуля до своего органайзера Урок 31 из 40
Option: когда записи может не быть
Урок 31. Искать название по позиции без аварии, если позиции нет.
Текст переведён с помощью ИИ.
Предварительно: уроки 15, 23–24 и 29–30. Если ветки match забылись, повторите урок 30.
Образ и опорная карта
В картотеке можно попросить карточку с номером, которого в лотке нет. Библиотекарь либо отдаёт карточку, либо честно говорит, что такой карточки нет. Option<T> — стандартное перечисление Rust для значения, которое может отсутствовать. Его варианты: Some(T) содержит значение типа T, None означает отсутствие. Образ ограничен: None не сообщает, почему карточки нет; для причины ошибки в следующем уроке понадобится другой тип.
Запрос → Option<T> → Some(значение) или None → обе ветки match. Угловые скобки из Vec<String> теперь указывают тип возможного содержимого. В Option<&String> возможное содержимое — ссылка на String, а не новая строка. Some и None доступны без дополнительной команды импорта. Нельзя считать, что Option<T> уже является T: сначала обработайте вариант.
Безопасно читаем список
Сохраните прежний src/main.rs проекта organizer, замените файл целиком и выполните cargo run рядом с Cargo.toml. Другие файлы и зависимости не меняются. Предскажите две строки вывода.
Метод .get(index) у Vec запрашивает элемент по позиции. В отличие от titles[index], неверная позиция не останавливает программу: результат имеет тип Option<&String>. Some(title) в match даёт имя ссылке на найденный текст; None обрабатывает отсутствие. Список создаётся знакомыми Vec::new() и push из урока 24. Индекс 0 существует, индекс 2 у списка длины 1 — нет.
fn main() {
let mut titles: Vec<String> = Vec::new();
titles.push(String::from("Чтение"));
for index in [0, 2] {
match titles.get(index) {
Some(title) => println!("Найдено: {title}"),
None => println!("Нет записи на позиции {index}"),
}
}
}
Найдено: Чтение
Нет записи на позиции 2
Список имеет один String. get не копирует название и не передаёт его владение: найденное значение заимствовано у titles.
Отсутствие не равно пустому тексту
Some(String::from("")) означает: значение есть, но текст пустой. None означает: значения вообще нет. Это разные состояния. None без подсказки о типе иногда не даёт компилятору понять, что могло бы быть внутри; запись let missing: Option<String> = None; явно задаёт тип. Для titles.get(index) тип уже известен из списка.
Если попробовать присвоить результат .get() обычной ссылке без разбора, компилятор остановит отдельный пример с E0308:
fn main() {
let mut titles: Vec<String> = Vec::new();
titles.push(String::from("Чтение"));
let title: &String = titles.get(0);
println!("{title}");
}
Правильный путь — match с Some и None или другой явно объяснённый способ обработки отсутствия. В органайзере позиции списка пока не являются постоянными ID задач: get лишь предотвращает выход за границу, но не решает задачу устойчивого номера из будущего урока 38.
Проверка понимания
- Чем
Option<&String>отличается от&String? - Означает ли
None, что найден пустой текст? - Почему
.get(2)не вызывает panic для списка длины 1?
Проверьте: ссылка может отсутствовать; нет, пустой текст тоже был бы значением; get возвращает None. Закройте страницу и восстановите опорную карту.
Задание
Обязательное. Создайте список с названиями Чтение и Прогулка. Через .get() запросите позиции 1 и 2 и обработайте обе через match. Выведите Найдено: Прогулка и Позиция 2 отсутствует. Не проверяйте длину вручную и не подставляйте готовое название в сообщение.
Граница. Создайте пустой список и объясните, что вернёт .get(0).
Подсказка
Для каждого index в [1, 2] выполните match titles.get(index). В Some(title) печатайте найденный title, в None — номер index.
Эталон после попытки
fn main() {
let mut titles: Vec<String> = Vec::new();
titles.push(String::from("Чтение"));
titles.push(String::from("Прогулка"));
for index in [1, 2] {
match titles.get(index) {
Some(title) => println!("Найдено: {title}"),
None => println!("Позиция {index} отсутствует"),
}
}
}
Найдено: Прогулка
Позиция 2 отсутствует
Здесь список остаётся владельцем названий, а отсутствие обрабатывается явно. Официальный разбор Option.
Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом
Комментарии (0)
Войдите, чтобы оставить комментарий →
Пока нет комментариев. Будьте первым.