liveBook · Manning

Empty slice

As explained in 100 Go Mistakes and How to Avoid Them

An empty slice is a Go slice whose length is zero, whether or not it has an allocated underlying array.

A slice is empty when its length is zero. A nil slice is therefore empty, but an empty slice is not necessarily nil. Confusing those tests can make code process a slice that contains no elements. section 3.6 section 3.7

func main() {
    var s []string         #1
    log(1, s)
 
    s = []string(nil)      #2
    log(2, s)
 
    s = []string{}         #3
    log(3, s)
 
    s = make([]string, 0)  #4
    log(4, s)
}
 
func log(i int, s []string) {
    fmt.Printf("%d: empty=%t\tnil=%t\n", i, len(s) == 0, s == nil)
}

Compare four zero-length initializations: the declaration and nil conversion produce nil slices; the literal and make call produce non-nil empty slices. section 3.6

Check for elements, not non-nilness

If getOperations returns make([]float32, 0), this condition still calls handle: ```go if operations != nil { handle(operations) } ``` Test the length instead. It works whether the returned empty slice is nil or non-nil: ```go if len(operations) != 0 { handle(operations) } ``` section 3.7

For a result assembled with append, start with `var s []string`: it needs no initial allocation, and append works on nil slices. If the result length is known, `make([]string, length)` lets you fill elements by index without growth-related allocations and copies. section 3.6

When nil and empty differ at a boundary

`encoding/json` encodes a nil slice field as `null` and a non-nil empty slice field as `[]`. Choose deliberately if that output matters, but do not use the distinction as the ordinary test for whether elements exist. section 3.6 section 3.7

Design slice-returning APIs so callers need not assign different meanings to nil and empty results. When consuming an API you cannot change, `len(s) == 0` remains the reliable empty check. section 3.7

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Defines empty and nil slices, compares initializations, and traces a failed element check through its length-based fix.
Examples
Contrasts four slice initializations, an operation handler’s nil check, and JSON outputs of null and an empty array.
What it assumes
Assumes familiarity with Go slices and functions while defining empty versus nil from first principles.
What you can do after
Apply length checks to detect empty slices and choose nil or allocated initialization according to construction and output needs.
How it connects
Connects slice length and nil values to append, allocation, API design, and JSON encoding.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.