0Pricing
Learn Rust Coding · Lesson

Entry API and Defaults

Update values ergonomically.

Entry API and Defaults is a free Learn Rust Coding lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why the Entry API?

Often you want to update a value if a key exists, or insert a default if it does not.

Doing this with get plus insert is clumsy. The entry API does it cleanly in one step.

entry Returns a Slot

Calling entry(key) gives you a handle to that key's place in the map.

From that handle you decide what to do: fill it with a default, or modify whatever is there.

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, i32> = HashMap::new();
    m.entry("a").or_insert(0);
    println!("{}", m["a"]);
}

or_insert

or_insert(default) inserts the default only if the key is missing, then returns a mutable reference to the value.

If the key already exists, the default is ignored and you get the existing value.

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("a", 10);
    m.entry("a").or_insert(99);
    m.entry("b").or_insert(99);
    println!("a={}, b={}", m["a"], m["b"]);
}

Mutating Through the Reference

Because or_insert returns a mutable reference, you can change the value right away.

Dereference it with * to update in place. This is the heart of counting.

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    let count = m.entry("hits").or_insert(0);
    *count += 1;
    *count += 1;
    println!("hits = {}", m["hits"]);
}

Counting in a Loop

The classic pattern: for each item, get its slot, default it to zero, and increment.

This tallies occurrences in just one line of logic per item.

use std::collections::HashMap;

fn main() {
    let mut counts = HashMap::new();
    for c in "hello".chars() {
        *counts.entry(c).or_insert(0) += 1;
    }
    println!("l appears {} times", counts[&'l']);
}

or_insert_with

When the default is expensive to build, use or_insert_with. It takes a closure that runs only if the key is missing.

This avoids constructing a value you might never need.

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, Vec<i32>> = HashMap::new();
    m.entry("nums").or_insert_with(Vec::new).push(1);
    m.entry("nums").or_insert_with(Vec::new).push(2);
    println!("{:?}", m["nums"]);
}

and_modify

and_modify runs a closure on the value only if the key already exists.

Chain it with or_insert to handle both cases: modify if present, otherwise insert a starting value.

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("x", 5);
    m.entry("x").and_modify(|v| *v += 10).or_insert(0);
    m.entry("y").and_modify(|v| *v += 10).or_insert(1);
    println!("x={}, y={}", m["x"], m["y"]);
}

or_default

If the value type has a Default (like 0 for integers or an empty Vec), or_default uses it.

It is a shorthand for or_insert(Default::default()).

use std::collections::HashMap;

fn main() {
    let mut m: HashMap<&str, i32> = HashMap::new();
    *m.entry("score").or_default() += 7;
    println!("score = {}", m["score"]);
}

Building Lists Per Key

The entry API shines when grouping items into vectors.

For each key, default to an empty Vec the first time, then push onto whatever vector is there.

use std::collections::HashMap;

fn main() {
    let mut groups: HashMap<bool, Vec<i32>> = HashMap::new();
    for n in [1, 2, 3, 4] {
        groups.entry(n % 2 == 0).or_default().push(n);
    }
    println!("evens: {:?}", groups[&true]);
}

Why Not get + insert?

Doing a separate get then insert looks up the key twice and fights the borrow checker.

The entry API does a single lookup and hands you exactly one safe reference, so it is faster and cleaner.

Putting It Together

Here counting and a default come together to find how many distinct words start with each letter.

Notice the one-line tally pattern in action.

use std::collections::HashMap;

fn main() {
    let words = ["ant", "art", "bee"];
    let mut by_first: HashMap<char, i32> = HashMap::new();
    for w in words {
        *by_first.entry(w.chars().next().unwrap()).or_insert(0) += 1;
    }
    println!("a: {}", by_first[&'a']);
}

Quick Check

You want to count chars with one lookup per char.

Recap

The entry API lets you insert-or-update in one lookup.

You used or_insert, or_insert_with, or_default, and and_modify to count items and build lists per key cleanly.

Frequently asked questions

Is the “Entry API and Defaults” lesson free?

Yes — the full text of “Entry API and Defaults” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “Entry API and Defaults”?

Update values ergonomically. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Entry API and Defaults” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Building a HashMap
  2. Entry API and Defaults
  3. Working with HashSet
  4. Counting and Grouping
← Back to Learn Rust Coding