Elete From A Map, And Is It
Fast recall
Quick revision
Core answer
Practical understanding of Map Iteration And Nil.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
Deletion is a one-way, no-feedback operation:
delete(m, "stale-key")There's no return value, no error, and no effect if the key doesn't exist. Deleting a missing key is a no-op, not a failure — the runtime probes for the entry and, finding none, does nothing. The same call works on a nil map without panic: probe nothing, do nothing.
That silence is the design question. Deletion being total (works on any input) means you never guard it — no 'if _, ok := m[k]; ok { delete(m, k) }' dance; just delete. But the flip side is you can't tell from the call whether anything happened. If you need 'was it there?', capture that with a lookup first:
if _, ok := m[k]; ok {
delete(m, k)
metrics.Evictions++
}The practical notes: deleting doesn't shrink the map's allocated capacity (memory isn't returned until the map is garbage), and deleting during range over the map is safe — the iteration contract allows deletion of not-yet-visited keys.
Elete From A Map, And Is It
Direct Answer
delete(m, key) — safe on any key, including missing ones, and on nil maps. No error, no return value.
Deep Dive & Architecture
Why is delete total while write panics on nil? The asymmetry has the same shape as the nil-map read rule: operations that need to 'find a place for something' require the structure to exist; operations that can honestly answer 'nothing there' don't.
Delete is a lookup plus an unlink: probe for the key; if absent, there's nothing to unlink — done. No structure needed to express 'no effect.' Write, by contrast, needs a bucket to put the entry into — hence the panic on nil.
The iterate-while-deleting rule comes from the iterator's contract: entries deleted before the iterator reaches them may or may not be visited (unspecified); entries that exist and aren't deleted will be. That's enough to write cleanup loops safely:
for k, v := range cache {
if v.expired() {
delete(cache, k)
}
}
The pattern works because deletion can't invalidate the iteration — the iterator holds its position in the bucket structure, and delete unlinks entries without moving where subsequent iteration resumes. Insert during iteration is the unspecified case to avoid.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Map Iteration And Nil, and when would you use it?
- When would you use Map Iteration And Nil in a real project?
- How would you compare Map Iteration And Nil with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.