Почему этот срез нулевой длины и нулевой емкости не равен нулю? - PullRequest
0 голосов
/ 25 октября 2019

Я прохожу учебник Go , и я достиг урока о ноль-срезах, где говорится:

Ноль-срез имеет длину и емкость 0 и имеетнет базового массива.

Чтобы показать это, они представляют этот код, который работает

package main

import "fmt"

func main() {
    var s []int 
    fmt.Println(s, len(s), cap(s))
    if s == nil {
        fmt.Println("nil!")
    }
}

Однако я попытался поэкспериментировать и заменил var s []int на s := []int{}. Консоль все еще печатает [] 0 0, как в первом случае, но больше не строка nil!. Так почему же первый nil, а другой нет?

1 Ответ

3 голосов
/ 25 октября 2019

Для s := []int{}:
Поскольку инициализируется новым типом (например, struct) с базовым массивом, длиной и емкостью

Срез, однажды инициализированный , всегда связан с базовым массивом, который содержит его элементы.

Для var s []int см. Типы срезов :

Значение неинициализированного среза равно нулю.

Нулевое значение :

Когда память выделяется для переменной, либо через объявление или вызов нового, либо когда новыйзначение создается с помощью составного литерала или вызова make, и явная инициализация не предоставляется, переменной или значению присваивается значение по умолчанию . Каждый элемент такой переменной или значения устанавливается равным нулевому значению для его типа: false для логических значений, 0 для числовых типов, "" для строк и nil для указателей, функций, интерфейсы, срезы , каналы и карты. Эта инициализация выполняется рекурсивно, поэтому, например, каждый элемент массива структур будет обнулять свои поля, если не указано значение.
Эти два простых объявления эквивалентны:

var i int
var i int = 0

После

type T struct { i int; f float64; next *T }
t := new(T)

справедливо следующее:

t.i == 0
t.f == 0.0
t.next == nil

То же самое будет верно и после

var t T

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...