get() and get_mut()
HashMap<K, V> provides .get(&q), .get_key_value(&q), .get_mut(&q), and .get_disjoint_mut([&q1, &q2]) for safe, non-panicking key lookups in $O(1)$ average time, alongside the panicking index operator map[&q].
Signatures and the Borrow<Q> Parameter
impl<K: Eq + Hash, V, S: BuildHasher> HashMap<K, V, S> {
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized;
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized;
pub fn get_mut<Q>(&self, k: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized;
}
Because get and get_mut accept any &Q where K: Borrow<Q> and Q: Hash + Eq + ?Sized, you can query a HashMap<String, V> using a &str literal or slice without allocating a temporary String!
| Lookup Expression | Return Type | Missing Key Behavior |
|---|---|---|
map.get(&q) |
Option<&V> |
Returns None |
map.get_key_value(&q) |
Option<(&K, &V)> |
Returns None |
map.get_mut(&q) |
Option<&mut V> |
Returns None |
map[&q] |
&V (shared only; IndexMut is not implemented!) |
Panics at runtime |
(Note: Unlike Vec<T>, HashMap<K, V> does not implement IndexMut (map[&k] = v does not exist), because map[&k] cannot know whether you intend to insert a new key or panic on a missing key; use map.insert(k, v) or *map.get_mut(&k).unwrap() = v instead.)
Querying and Mutating Values with get() and get_mut()
use std::collections::HashMap;
fn main() {
let mut balances = HashMap::from([
(String::from("alice"), 500_i64),
(String::from("bob"), 250),
]);
// 1. Lookup on `HashMap<String, i64>` using a `&str` slice (via `String: Borrow<str>`):
let alice_bal: Option<i64> = balances.get("alice").copied();
let unknown_bal: Option<i64> = balances.get("charlie").copied();
println!("Alice: {alice_bal:?}, Charlie: {unknown_bal:?}");
// 2. Mutate an existing value in place with `get_mut`:
if let Some(bal) = balances.get_mut("bob") {
*bal += 100;
}
println!("Bob after deposit: {}", balances["bob"]);
}
Alice: Some(500), Charlie: None
Bob after deposit: 350
Mutating Multiple Keys Simultaneously with get_disjoint_mut
Just like Vec::get_disjoint_mut, map.get_disjoint_mut([&k1, &k2]) returns [Option<&mut V>; N] (or panics if k1 == k2), allowing you to mutate two distinct keys in the same HashMap at the same time:
use std::collections::HashMap;
fn main() {
let mut accounts = HashMap::from([("alice", 1_000_i64), ("bob", 400)]);
if let [Some(from), Some(to)] = accounts.get_disjoint_mut(["alice", "bob"]) {
*from -= 250;
*to += 250;
}
println!("alice={}, bob={}", accounts["alice"], accounts["bob"]);
}
alice=750, bob=650