Zero Value Of A Slice And What
Fast recall
Quick revision
Core answer
Practical understanding of Slice Internals Len Cap.
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 declared-but-unassigned slice is nil — the header's pointer is null, len and cap zero. But unlike a nil map, which panics on writes, a nil slice is mostly usable:
len(nil-slice) is 0, cap is 0. Ranging over it executes zero iterations — loop bodies just don't run. Append works, and it's not a special case: appending to a zero-cap slice takes the allocate path (there's no room), so var s []int; s = append(s, x) behaves exactly like starting from []int{}. JSON marshals it as null (that's the visible difference from an empty-but-non-nil slice, and it matters for APIs).
What you cannot do: index into it — s[0] on a nil slice panics with index out of range, same as any over-index. And functions that check if s == nil for emptiness will distinguish nil from empty; for most purposes len(s) == 0 is the correct emptiness test because it covers both.
Zero Value Of A Slice And What
Direct Answer
nil. You can len it (0), range it (no iterations), append to it (allocates), and delete-free operations are fine. Only indexing panics — and writing to a nil map's sibling panic is different: nil slice writes work via append.
Deep Dive & Architecture
The nil slice's usability is a deliberate design choice — it makes the accumulate idiom work without initialization:
var results []string
for _, r := range raw {
if keep(r) {
results = append(results, clean(r))
}
}
// no make() needed up front; nil grows on first append
Compare the map: var m map[string]int; m["k"] = 1 panics (assignment to entry in nil map) because a map needs its hash structure initialized by make before any write can find a bucket. A slice's structure is the header itself — three words, all validly zero — and the backing array only needs to exist once there's something to store, which is exactly when append allocates it.
The nil vs empty distinction surfaces at boundaries: json.Marshal(nil) gives null, json.Marshal([]int{}) gives [] — API consumers notice. len(s) == 0 treats both as empty, which is almost always what logic wants. Reserve s == nil for the rare case where the distinction is the signal (an absent field vs a present-but-empty list).
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 Slice Internals Len Cap, and when would you use it?
- When would you use Slice Internals Len Cap in a real project?
- How would you compare Slice Internals Len Cap with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.