What does the built-in clear() do for slices vs maps?
Question 65MediumGo 1.22 to 1.25
clear (Go 1.21) has different semantics depending on the type:
- Map: deletes every entry, so
lenbecomes 0. It is the only way to remove NaN keys, and it is faster than looping overdelete. - Slice: sets every element up to
len(s)to its zero value.lenandcapdo not change. It does not "empty" the slice. - Type parameter: the type set must be all maps or all slices.
s := []int{1, 2, 3}
clear(s)
fmt.Println(s, len(s)) // [0 0 0] 3
m := map[string]int{"a": 1, "b": 2}
clear(m)
fmt.Println(m, len(m)) // map[] 0
// Reuse a buffer: truncate + zero (zeroing matters for pointer elements / secrets)
buf := []*Node{ /* ... */ }
clear(buf) // drop references so the GC can free the Nodes
buf = buf[:0] // now empty, capacity retained
// Only affects [0:len], not the hidden tail up to cap
t := make([]int, 2, 4)
t = append(t, 7, 8)[:2]
clear(t)
fmt.Println(t[:4]) // [0 0 7 8]
Gotcha: people coming from other languages expect clear(s) to act like s = s[:0]. In Go you need both lines. The compiler turns for i := range s { s[i] = zero } into a memclr call, and clear makes that intent explicit.
More on Arrays, Slices, Maps & Strings
- Q63Which types can be map keys? What happens with interface keys and NaN?
- Q64Do Go maps shrink after deleting entries? How do you reclaim memory?
- Q66Explain nil map behaviour and what happens when you pass a map to a function.
- 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.