Какая длина (`len`) и емкость (`capacity`) у `nil`-слайса?

Ответ

У неинициализированного (nil) слайса и длина (len), и емкость (capacity) равны 0.

package main

import "fmt"

func main() {
    var s []int

    fmt.Println(s == nil)   // true
    fmt.Println(len(s))     // 0
    fmt.Println(cap(s))     // 0
}

Ключевые свойства nil-слайса:

  • Он не указывает ни на какой нижележащий массив (s == nil).
  • Его длина и емкость равны нулю.
  • Несмотря на это, в него можно безопасно добавлять элементы с помощью append. При этом будет создан новый слайс с новым нижележащим массивом.

Важное различие: nil-слайс vs пустой слайс

Не стоит путать nil-слайс с пустым, но не nil слайсом.

var nilSlice []int
emptySlice := make([]int, 0) // или emptySlice := []int{}

// Оба имеют одинаковые len и cap
fmt.Println(len(nilSlice), cap(nilSlice))     // 0 0
fmt.Println(len(emptySlice), cap(emptySlice)) // 0 0

// Но один из них nil, а другой - нет
fmt.Println(nilSlice == nil)   // true
fmt.Println(emptySlice == nil) // false

Пустой слайс (emptySlice) указывает на существующую, но пустую структуру данных в памяти, в то время как nilSlice не указывает никуда.