1. Vec<T> — growable array
let mut v: Vec<i32> = vec![1, 2, 3];
v.push(4);
let x = &v[0]; // panics on out-of-range
let x = v.get(1); // Option — safe
getreturnsOption; indexing panics.- Iterating moves by default — use
&vfor borrows.
2. HashMap<K, V>
use std::collections::HashMap;
let mut m = HashMap::new();
m.insert("k", 5);
if let Some(v) = m.get("k") { println!("{v}"); }
getreturns Option; entry API avoids double lookup.- Iteration order is unspecified.
3. String vs &str — the FAQ
String= owned, mutable heap buffer.&str= borrowed reference to UTF-8 bytes (slices).
let s: String = String::from("hi");
let t: &str = &s; // borrow a string
let literal: &str = "hello"; // &'static str
Key facts:
- Indexing
s[0]is not allowed — UTF-8 boundaries. Use.chars().nth(0)or.as_bytes(). StringimplementsDeref<Target = str>so&Stringcoerces to&str..chars()iterates Unicode scalar values;.bytes()raw bytes.format!macro builds strings;push_strappends.
4. ? and error propagation
use std::fs::File;
fn open(path: &str) -> Result<File, std::io::Error> {
File::open(path) // Ok(File) or Err — bubbles up with ?
}
Becomes:
fn open(path: &str) -> Result<File, std::io::Error> {
Ok(File::open(path)?) // ? returns early on Err
}
Result<T, E>→?in a function returning Result;Optionin Option-returning fns.Box<dyn Error>/anyhowfor aggregating different error types.
5. Iterators & closures
v.iter().map(|x| x * 2).filter(|x| x > 4).collect::<Vec<_>>();
iter()borrows;into_iter()consumes;iter_mut()mutates.collectneedsType ascriptionor a type hint.- Closures capture environment;
moveclosure takes ownership.
6. Interview checkpoint
- Vec vs array vs slice; index vs
.get(). - HashMap entry API; iteration order.
- String vs &str — memory + indexing.
?operator semantics.- lazy iterators vs eager Vec operations.
Premium Content
Unlock Part 4: Collections, Strings & Error Handling and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans