a common mistake when using Method Sets
Fast recall
Quick revision
Core answer
Practical understanding of Method Sets.
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
The error, verbatim (executed): 'cannot call pointer method Inc on U' — triggered when the receiver expression can't be address-taken:
m := map[string]User{"x": {Age: 1}}
m["x"].Inc() // compile error — m["x"] is non-addressable
User{Name: "t", Age: 1}.Inc() // compile error — a temporary
u := User{Age: 1}
u.Inc() // works — u is a variable (addressable)
s := []User{{Age: 1}}
s[0].Inc() // works — slice elements are addressableThe rule the compiler implements: x.Inc() (pointer method) on a value x compiles only when x is addressable — because the call needs (&x).Inc(), and &x requires a real storage location. Variables, slice elements, struct fields reachable through addressable chains — all have addresses. Map values, function returns, expression temporaries — the storage either isn't stable (map internals move elements during growth) or never existed as a named location.
Why map elements specifically: the map's hash table can relocate entries (growth, evacuation) — an address into it would dangle. That's the same reason map values can't be taken as & at all. The workarounds each express the real fix — take the value out, modify, put back:
u := m["x"] // copy out
u.Inc() // mutate the copy
m["x"] = u // store backor store pointers in the map (map[string]*User) — the map's VALUES are pointer headers (stable to copy), the pointees live at fixed heap addresses, and m["x"].Inc() works because the address being taken is the POINTER variable's target, not a map slot.
a common mistake when using Method Sets
Direct Answer
Non-addressable values: map elements, function returns, temporary literals. The call needs the receiver's address to pass; non-addressable storage has none. Variables and slice elements ARE addressable — the shorthand works there.
Deep Dive & Architecture
Addressability is a property of EXPRESSIONS, not types — the spec's concept that ties this together. An expression is addressable if it denotes a stable storage location: variables (always), pointer dereferences (*p — the pointee is addressable through p), slice indexing (s[i] — the array slot), field selectors through addressable chains (u.Field, s[0].Field). Not addressable: map indexing (the slot can move), function/method return values (temporary), composite literals in expressions (temporary), constants (no storage).
The unify rule: &x is legal exactly when x is addressable — and x.PtrMethod() needs (&x) — so the set of legal pointer-method calls IS the addressable set. That's why the errors group the way they do, and why the fix is always 'get the value into a variable' (a variable being the canonical addressable thing).
The pointer-in-the-map pattern's mechanics: map[string]*User stores one-word pointer values. m["x"] returns a copy of the POINTER (cheap, stable) — the pointer value is addressable as a map value? No — but it doesn't need to be: the method call needs the RECEIVER's address, and the receiver *User is a pointer already — its address (the pointee's address) exists in the heap regardless of where the map's copy of the pointer lives. The non-addressability of map values applies to the POINTER variable — but pointer methods on a pointer receiver don't need the variable's address, they need the pointee — heap-stable. That's the deep reason map[string]*User + pointer methods just works.
The escape-analysis coda: addressable locals + pointer methods = the receiver's address escapes into the call — the compiler must keep the variable somewhere with a stable address for the call's duration. Usually stack; heap if the method stores the pointer. Non-addressable receivers would break this model (a temporary's 'address' would have to be the call frame — which is why temporaries simply can't take pointer methods; there's no stable there to point at).
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 Method Sets, and when would you use it?
- When would you use Method Sets in a real project?
- How would you compare Method Sets with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.