
Go slices are dynamic, reference-like views into underlying arrays—nil slices behave identically to zero-length slices and support append without prior allocation.
go slices are dynamic, reference-like views into underlying arrays—nil slices behave identically to zero-length slices and support `append` without prior allocation.
In Go, a slice is not an array—it’s a lightweight descriptor containing three fields: a pointer to an underlying array, a length (len), and a capacity (cap). This design enables efficient, flexible data handling while abstracting memory management.
For example:
<code class="go">a := make([]int, 7, 15)</code>
creates a slice with len = 7 and cap = 15, backed by an underlying array of 15 integers. The slice references the first 7 elements—but does not copy them. It’s a “shallow view”, not a shallow copy in the traditional sense (no data duplication occurs).
Conversely:
<code class="go">var a []int // a is nil — zero value of slice type</code>
declares a nil slice: it has len = 0, cap = 0, and its underlying pointer is nil. Crucially—and this often surprises newcomers—a nil slice is functionally equivalent to a zero-length slice ([]int{} or make([]int, 0)). You can safely call:
<code class="go">a = append(a, 9, 86)</code>
Go detects the nil state, allocates a new underlying array (typically with capacity ≥2, often exactly 2 for small appends), stores the values, and returns a fresh slice pointing to it. No panic, no manual initialization required.
✅ Key takeaways:
-
nilandlen == 0slices are interchangeable for reading, iterating, and appending. -
appendhandles allocation automatically—even on nil slices. - Use
make([]T, 0, n)only when you want to pre-allocate capacity (e.g., to avoid reallocations in known-size scenarios). - Avoid premature
makefor empty slices unless you need explicit capacity control or wish to distinguishnilfrom non-nil empty slices (e.g., for JSON marshaling wherenilbecomesnull, but[]int{}becomes[]).
Remember: Go’s slice semantics prioritize ergonomics and safety. Trust append, embrace nil, and let the runtime optimize.










