Что такое нулевое значение (zero value) для слайса в Go и как оно отличается от пустого слайса?

Ответ

В Go нулевое значение (zero value) для слайса — это nil. Это означает, что слайс не инициализирован и не ссылается ни на какой базовый массив.

Пример:

var s []int // s имеет нулевое значение nil
fmt.Println(s == nil) // true
fmt.Println(len(s))   // 0
fmt.Println(cap(s))   // 0

Чтобы создать пустой, но не nil слайс (который ссылается на базовый массив нулевой длины), можно использовать:

s := []int{} // s не nil, но len(s) == 0 и cap(s) == 0
fmt.Println(s == nil) // false

Ключевые отличия и поведение:

  • nil слайс:
    • s == nil вернет true.
    • len(s) и cap(s) вернут 0.
    • Можно безопасно использовать в функциях len(), cap(), append(). append на nil слайсе корректно его инициализирует.
    • При сериализации в JSON (json.Marshal(nilSlice)) будет представлен как null.
  • Пустой (но не nil) слайс ([]int{} или make([]int, 0)):
    • s == nil вернет false.
    • len(s) и cap(s) вернут 0.
    • При сериализации в JSON (json.Marshal(emptySlice)) будет представлен как [] (пустой JSON-массив).

Лучшая практика:
В Go-функциях часто рекомендуется возвращать nil для слайсов, если нет элементов, так как это более идиоматично и явно указывает на отсутствие данных. Однако, если API (например, JSON) требует явного пустого массива [], то может быть предпочтительнее возвращать []int{}.