Explain nil map behaviour and what happens when you pass a map to a function.
Question 66MediumGo 1.22 to 1.25
A map variable is a pointer to a runtime header. Passing it copies the pointer, so inserts and deletes inside the callee are visible to the caller, without needing *map. Reassigning the parameter (m = make(...)) affects only the callee's copy.
A nil map acts as an empty, read-only map. Reads return the zero value, and len, range, delete and clear all work. Writes panic with assignment to entry in nil map.
func fill(m map[string]int) { m["a"] = 1 }
func reset(m map[string]int) { m = map[string]int{} } // no effect on caller
func main() {
var nilMap map[string]int
fmt.Println(nilMap["x"], len(nilMap)) // 0 0
delete(nilMap, "x") // OK, no-op
for range nilMap {} // OK
// nilMap["x"] = 1 // panic: assignment to entry in nil map
m := map[string]int{}
fill(m)
reset(m)
fmt.Println(m) // map[a:1]
}
// Common bug: struct with a map field used via its zero value
type Registry struct{ items map[string]int }
func (r *Registry) Add(k string) {
if r.items == nil { // lazy init makes the zero value usable
r.items = make(map[string]int)
}
r.items[k]++
}
Signal: you design types so their zero value is useful (lazy init, like sync.Mutex or bytes.Buffer). When decoding JSON into a struct, remember that nested map fields start as nil until the decoder allocates them.
More on Arrays, Slices, Maps & Strings
- Q64Do Go maps shrink after deleting entries? How do you reclaim memory?
- Q65What does the built-in clear() do for slices vs maps?
- Q67Why are strings immutable in Go, and what does converting between string and []byte cost?
- Q68What does this print? (len, indexing and ranging over a UTF-8 string)
- Q69How do you build strings efficiently? Compare +, fmt.Sprintf, bytes.Buffer and strings.Builder.
- Q70How do you convert between []byte and string without copying, and what are the risks?