Go

Why can't you take the address of a map element (&m[k]), when you can with slice elements?

Question 62MediumGo 1.22 to 1.25

Because the runtime moves map entries. When a map grows (classic evacuation, or a Swiss-table split), entries are rehashed and copied to new memory. A pointer from &m[k] would then point at stale memory: the old bucket. Writes through it would be lost, or would corrupt a reused slot. The language rules this out by making map index expressions non-addressable.

A slice element's address is safe because the backing array never moves. append may allocate a new array, but the old one stays valid as long as something references it. So &s[i] is memory-safe. It can still be semantically stale after an append that reallocates.

// m := map[string]int{"a": 1}
// p := &m["a"] // compile error: cannot take address of m["a"]

s := []int{1, 2, 3}
p := &s[0]
s = append(s, 4)   // cap was 3 -> reallocates
*p = 100
fmt.Println(s[0])  // 1: p still points into the OLD array (safe, but stale)

Follow-up interviewers like: "Then how does m[k]++ work?" The compiler lowers it to a runtime call such as mapassign. That call returns an internal pointer to the slot, which is used right away before anything can trigger growth. User code never gets hold of that pointer.

More on Arrays, Slices, Maps & Strings

All 37 Arrays, Slices, Maps & Strings questions