Hash Map — это коллекция пар “ключ-значение”, которая позволяет быстро находить значения по ключу. Представьте ее как справочник, где вы моментально получаете нужную информацию.
Для создания пустого HashMap используется функция HashMap::new(). Чтобы наполнить коллекцию данными, её необходимо сделать изменяемой с помощью ключевого слова mut, после чего использовать метод insert(key, value).
Давайте посмотрим на интерактивном слайде, как создаётся HashMap, вставляются новые значения и как обновить существующее значение:
Базовые операции с HashMap: создание, вставка и обновление
Шаг 1/2
1usestd::collections::HashMap; 2 3fnmain(){ 4// Создаем изменяемый HashMap
5letmutsmart_home=HashMap::new(); 6 7// Добавляем устройства и их состояние
8smart_home.insert("гостиная_свет".to_string(),"включен".to_string()); 9smart_home.insert("спальня_термостат".to_string(),"22°C".to_string());1011println!("Устройства: {:?}",smart_home);12}
Создание HashMap и добавление элементов
Для использования HashMap импортируем его из std::collections.
Чтобы наполнить коллекцию данными, она должна быть объявлена изменяемой (mut).
Метод insert(key, value) добавляет новую пару ключ-значение в мапу.
Результат выполнения:
1usestd::collections::HashMap; 2 3fnmain(){ 4letmutsmart_home=HashMap::new(); 5smart_home.insert("гостиная_свет".to_string(),"включен".to_string()); 6smart_home.insert("спальня_термостат".to_string(),"22°C".to_string()); 7 8// Обновляем значение по существующему ключу
9smart_home.insert("гостиная_свет".to_string(),"выключен".to_string());1011println!("Обновленные устройства: {:?}",smart_home);12}
Обновление значения по ключу
Если мы вызываем insert с ключом, который уже существует в HashMap, старое значение перезаписывается новым.
При поиске значений в HashMap по ключу основным инструментом является метод .get(). Он возвращает перечисление Option<&V>, что защищает программу от ошибок обращения к отсутствующим элементам. Также Rust предоставляет мощный Entry API для условных операций (добавление или изменение значений только при выполнении определенных условий).
Давайте подробно разберем, как искать элементы, обрабатывать их отсутствие и использовать Entry API на интерактивном слайде:
Поиск значений, unwrap_or и Entry API
Шаг 1/3
1usestd::collections::HashMap; 2 3fnmain(){ 4letmutsmart_home=HashMap::new(); 5smart_home.insert("гостиная_свет","включен"); 6 7// Метод get() возвращает Option<&V>
8letlight_status=smart_home.get("гостиная_свет"); 9letlock_status=smart_home.get("дверь_замок");1011println!("Свет в гостиной: {:?}",light_status);12println!("Замок двери: {:?}",lock_status);13}
Поиск значений по ключу через .get()
Метод .get() принимает ссылку на ключ и возвращает Option<&V>.
Если ключ найден, возвращается Some(&value). Если ключа нет, возвращается None.
Это позволяет безопасно проверять наличие данных без риска паники во время работы.
Результат выполнения:
1usestd::collections::HashMap; 2 3fnmain(){ 4letmutsmart_home=HashMap::new(); 5smart_home.insert("гостиная_свет","включен"); 6 7// Получаем значение с дефолтом, если ключ отсутствует
8letdefault_status="выключен"; 9letlight=smart_home.get("гостиная_свет").unwrap_or(&default_status);10letlock=smart_home.get("дверь_замок").unwrap_or(&default_status);1112println!("Свет: {}",light);13println!("Замок: {}",lock);14}
Безопасное извлечение с unwrap_or
Метод .unwrap_or() позволяет задать запасное значение, которое будет использовано, если .get() вернул None.
Результат выполнения:
1usestd::collections::HashMap; 2 3fnmain(){ 4letmutsmart_home=HashMap::new(); 5smart_home.insert("гостиная_свет".to_string(),"включен".to_string()); 6 7// or_insert добавляет значение, только если ключа нет
8smart_home.entry("кухня_чайник".to_string()).or_insert("выключен".to_string()); 9smart_home.entry("гостиная_свет".to_string()).or_insert("включен".to_string());1011// and_modify изменяет значение, только если ключ есть
12smart_home.entry("гостиная_свет".to_string())13.and_modify(|status|*status="выключен".to_string());1415println!("Итоговое состояние: {:?}",smart_home);16}
Entry API: or_insert и and_modify
Метод .entry() возвращает перечисление Entry, представляющее запись (присутствующую или отсутствующую).
Метод .or_insert() вставляет значение, только если ключа нет, и возвращает мутабельную ссылку на значение.
Метод .and_modify() позволяет выполнить замыкание для изменения существующего значения по ключу.
Обработка отсутствующих ключей с помощью сопоставления с образцом (match):
Поскольку .get() возвращает Option<&V>, вы можете использовать сопоставление шаблонов для детальной обработки обоих сценариев (Some и None):
matchsmart_home_devices.get("гостиная_свет"){Some(status)=>println!("Статус света: {}",status),None=>println!("Статус света не найден"),}
Значения по умолчанию с unwrap_or:
Если вместо детальной обработки match вам достаточно подставить стандартное значение в случае отсутствия ключа, используйте метод .unwrap_or():
Давайте рассмотрим практический пример, связанный с управлением умным домом. Предположим, у нас есть несколько устройств в доме и нам нужно отслеживать их текущий статус. Например, мы хотим знать, включен ли свет в гостиной, какая температура установлена на термостате в спальне и работает ли кондиционер на кухне. Если статус какого-то устройства неизвестен, мы хотим выводить соответствующее сообщение.
У нас есть список всех устройств, которые нас интересуют.
Для каждого устройства нужно вывести его название и текущий статус из HashMap, подставив значение по умолчанию для неизвестных приборов.
Давайте посмотрим, как работает этот алгоритм на практике с помощью интерактивного слайда:
Практический пример: Мониторинг умного дома
1usestd::collections::HashMap; 2 3fnmain(){ 4// Создаем HashMap для хранения статусов устройств
5letmuthome_device_status: HashMap<String,String>=HashMap::new(); 6 7// Добавляем статусы для некоторых устройств
8home_device_status.insert("гостиная_свет".to_string(),"включен".to_string()); 9home_device_status.insert("спальня_термостат".to_string(),"22°C".to_string());1011// Список интересующих нас приборов
12letdevices=vec!["гостиная_свет","спальня_термостат","кухня_кондиционер"];13letdefault_device_status="статус неизвестен".to_string();1415// Перебираем все устройства и выводим их статус
16fordeviceindevices{17letstatus=home_device_status.get(device).unwrap_or(&default_device_status);18println!("{}: {}",device,status);19}20}
Практический пример: Мониторинг умного дома
Мы обходим вектор интересующих нас приборов и ищем состояние каждого в HashMap.
Для прибора кухня_кондиционер, которого нет в мапе, метод .unwrap_or() подставляет запасное значение статус неизвестен.
HashMap предоставляет мощный способ работы с парами “ключ-значение”. Они идеально подходят для задач, требующих быстрого поиска и эффективного управления данными.
Используйте HashMap, когда:
Вы хотите связать произвольный ключ с произвольным значением.
Вам нужен кэш.
Вам нужна эффективная ассоциативная коллекция без сохранения порядка вставки.