Collections and the Standard Library
HashMap<K, V> stores key-value pairs, just like a dictionary in Python or an object in JavaScript — but with both the key and value types fixed up front. Indexing with [] panics if the key is missing, while .get() returns an Option, letting you handle a missing key without crashing.
use std::collections::HashMap;
fn main() {
let mut scores: HashMap<String, i32> = HashMap::new();
scores.insert(String::from("Alice"), 95);
scores.insert(String::from("Bob"), 87);
println!("{}", scores["Alice"]);
if let Some(score) = scores.get("Bob") {
println!("Bob: {}", score);
}
}95 Bob: 87
The entry API
entry().or_insert() is Rust's idiomatic way to update-or-insert in one step: it returns a mutable reference to the value, inserting a default first if the key wasn't already there. contains_key checks for a key's presence without needing to handle an Option at all.
use std::collections::HashMap;
fn main() {
let mut inventory: HashMap<&str, i32> = HashMap::new();
inventory.insert("apples", 10);
inventory.insert("bananas", 5);
*inventory.entry("apples").or_insert(0) += 3;
println!("apples: {}", inventory["apples"]);
println!("has oranges: {}", inventory.contains_key("oranges"));
}apples: 13 has oranges: false
That's the foundation of Rust: ownership, borrowing, and a type system that turns whole categories of bugs into compile errors instead of runtime surprises. From here, the best next step is practice — pick a small program and build it, leaning on the compiler's error messages, which are some of the best in the industry, to guide you.
Practice exercise
Create a HashMap<&str, i32> named ages. Insert "Alice" -> 30 and "Bob" -> 25. Print ages["Alice"].