Подтвердить что ты не робот

Правильный способ инициализации пустого среза

Чтобы объявить пустой фрагмент с нефиксированным размером, лучше сделать:

mySlice1 := make([]int, 0)

или же:

mySlice2 := []int{}

Просто интересно, какой из них правильный.

4b9b3361

Ответ 1

Два варианта, которые вы дали, семантически идентичны, и я бы предположил, что они производят одинаковые инструкции по сборке.

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

var myslice []int

Как написано в блоге Golang.org:

нулевой срез функционально эквивалентен срезу нулевой длины, даже если он ничего не указывает. Он имеет нулевую длину и может быть добавлен с выделением.

Ответ 2

Они эквивалентны. Смотрите этот код:

mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))

Выход:

mySlice1 0
mySlice2 0

Оба среза имеют емкость 0 что означает, что оба среза имеют длину 0 (не может быть больше емкости), что означает, что оба среза не имеют элементов. Это означает, что 2 среза идентичны в каждом аспекте.

Смотрите похожие вопросы:

Какой смысл иметь нулевой ломтик и пустой ломтик в Голанге?

ноль ломтиков против не ноль ломтиков против пустых ломтиков на языке Go

Ответ 3

В качестве дополнения к @ANisus ' ответьте...

ниже приведена некоторая информация из книги "Идите в действии", о которой я думаю стоит упомянуть:

Разница между nil и empty срезами

Если мы подумаем о таком фрагменте:

[pointer] [length] [capacity]

то

nil slice:   [nil][0][0]
empty slice: [addr][0][0] // points to an address

nil slice

Theyre полезно, когда вы хотите представить фрагмент, который не существует, например, когда возникает исключение в функции, которая возвращает срез.

// Create a nil slice of integers.
var slice []int

пустой фрагмент

Пустые фрагменты полезны, когда вы хотите представлять пустую коллекцию, например, когда запрос базы данных возвращает нулевые результаты.

// Use make to create an empty slice of integers.
slice := make([]int, 0)

// Use a slice literal to create an empty slice of integers.
slice := []int{}

Независимо от того, используете ли вы nil-фрагмент или пустой фрагмент, встроенные функции append, len и cap работают одинаково.


Перейти к игровой площадке:

package main

import (
    "fmt"
)

func main() {

    var nil_slice []int
    var empty_slice = []int{}

    fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))
    fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))

}

печатает:

true 0 0
false 0 0

Ответ 4

Пустой срез и нулевой фрагмент инициализируются по-разному в Go:

var nilSlice []int 
emptySlice1 := make([]int, 0)
emptySlice2 := []int{}

fmt.Println(nilSlice == nil)    // true
fmt.Println(emptySlice1 == nil) // false
fmt.Println(emptySlice2 == nil) // false

Как и для всех трех срезов, len и cap имеют значение 0.

Ответ 5

Я был смущен по поводу слов:

Чтобы избежать ненужного выделения, в случае, если вы в конечном итоге не используете срез, вы можете оставить его с нулевым значением.

Поскольку выходы ниже одинаковы, поэтому у меня нет гостя с пустым слайсом.

    var a = []int{}
    var b = []string{}
    var c = []interface{}{}
    fmt.Printf("%p\n", a)
    fmt.Printf("%p\n", b)
    fmt.Printf("%p\n", c)

выход:

0xd301f0 0xd301f0 0xd301f0