Map Keys Work — What Types Can
Fast recall
Quick revision
Core answer
Practical understanding of Maps Make And Literal.
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
A key type must support equality, because a hash table needs to (1) hash the key and (2) compare a probed key against the stored one. Anything with == defined can be a key: strings, all numeric types, bools, pointers, channels, interfaces, arrays, and structs whose fields are all comparable.
What can't: slices, maps, and functions. == is not defined for them (comparing two slices can't answer 'same contents?' cheaply and Go refuses reference-vs-content ambiguity), so they can't hash or match. A struct containing a slice field inherits the restriction — no == for the struct, no key.
The practically valuable cases beyond strings and ints:
// struct keys — composite lookups
key := struct{ Region, AZ string }{"us-east", "1a"}
counts[key]++
// array keys — fixed-size sequences
var ip [4]byte
copy(ip[:], bytes)
seen[ip] = trueStruct keys are the underrated one: a small comparable struct gives you multi-field lookup keys without string-concatenation or nested maps. The rule is just the == rule — and the compile error for a bad key type (invalid map key type) is the language teaching it at build time.
Map Keys Work — What Types Can
Direct Answer
Any comparable type: strings, ints, bools, arrays, structs of comparables, pointers, interfaces. NOT slices, maps, or functions — they have no ==.
Deep Dive & Architecture
Why is == the gate? Trace the hash-table operations:
insert: hash(k) → bucket → store (k, v). The key must hash stably. lookup: hash(k) → bucket → compare k against stored keys with ==. Equality must match hash equality.
Both operations lean on the same two properties: a stable hash and a well-defined equality that agrees with it. Slices break both: contents mutate (hash rots) and == between two slice headers checks pointer+len — not the semantics a lookup wants. Go's designers chose to exclude rather than pick a semantics (deep-equal keys would need O(n) compares per probe and a defined deep-hash) — the constraint pushes you toward strings, ints, and structs, which cover real key shapes honestly.
The mutability subtlety for struct keys: == compares FIELDS, so two struct keys with equal fields are the same key — value semantics. But if the struct contains a POINTER field, == compares the pointer, and two structs pointing at equal-but-distinct data are different keys. The key's behavior is exactly its =='s behavior — no more, no less. When that surprises, the fix is storing the data you match on (the dereferenced values) in the key, not the pointer.
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 Maps Make And Literal, and when would you use it?
- When would you use Maps Make And Literal in a real project?
- How would you compare Maps Make And Literal with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.