Чтобы объявить пустой фрагмент с нефиксированным размером, лучше сделать:
mySlice1 := make([]int, 0)
или же:
mySlice2 := []int{}
Просто интересно, какой из них правильный.
Чтобы объявить пустой фрагмент с нефиксированным размером, лучше сделать:
mySlice1 := make([]int, 0)
или же:
mySlice2 := []int{}
Просто интересно, какой из них правильный.
Два варианта, которые вы дали, семантически идентичны, и я бы предположил, что они производят одинаковые инструкции по сборке.
Чтобы избежать ненужного выделения, в случае, если вы в конечном итоге не используете срез, вы можете оставить его с nil
значением:
var myslice []int
Как написано в блоге Golang.org:
нулевой срез функционально эквивалентен срезу нулевой длины, даже если он ничего не указывает. Он имеет нулевую длину и может быть добавлен с выделением.
Они эквивалентны. Смотрите этот код:
mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))
Выход:
mySlice1 0
mySlice2 0
Оба среза имеют емкость 0
что означает, что оба среза имеют длину 0
(не может быть больше емкости), что означает, что оба среза не имеют элементов. Это означает, что 2 среза идентичны в каждом аспекте.
Смотрите похожие вопросы:
Какой смысл иметь нулевой ломтик и пустой ломтик в Голанге?
ноль ломтиков против не ноль ломтиков против пустых ломтиков на языке Go
В качестве дополнения к @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
Пустой срез и нулевой фрагмент инициализируются по-разному в 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.
Я был смущен по поводу слов:
Чтобы избежать ненужного выделения, в случае, если вы в конечном итоге не используете срез, вы можете оставить его с нулевым значением.
Поскольку выходы ниже одинаковы, поэтому у меня нет гостя с пустым слайсом.
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