Slices, maps and strings · 3 MIN READ
A nil slice is empty, and append still works
Predict what len, == nil and append do to a zero slice.
The Tour's "Nil slices" page: the zero value of a slice is nil, it has length and capacity 0, and it has no backing array. append treats that as a valid empty slice and allocates. JSON encodes a nil slice as null and a non-nil empty one as [] — the only common place the distinction leaks out.
s == nil is true for var s []int and false for s := []int{}. Both have len 0. Prefer len(s) == 0 unless you are talking to a wire format that cares.
SEE THE IDEA
A nil slice already supports empty operations
- 01
Start
govar values []intLength and capacity are zero
- 02
Grow
govalues = append(values, 9)Append allocates when needed
- 03
Use
gorange valuesAn empty slice runs zero iterations
Nil and empty slices behave alike for length, range and append.
In practice
Return a nil slice when no results is a natural zero value, unless the API requires a non-nil empty value. Most callers should inspect length rather than compare to nil. Encoders may distinguish the two representations, so document the serialized contract when it matters.
Watch out
The standard encoding/json package encodes a nil slice as null and a non-nil empty slice as [].
Read and predict
package main
import "fmt"
func main() {
var s []int
fmt.Println(s == nil, len(s), cap(s))
s = append(s, 1)
fmt.Println(s == nil, len(s), s[0])
empty := []int{}
fmt.Println(empty == nil, len(empty))
}What does this print?
Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.
Progress stays in this browser. No account needed.