Чтобы объявить пустой фрагмент с нефиксированным размером, лучше сделать:
mySlice1 := make([]int, 0)
или:
mySlice2 := []int{}
Просто интересно, какой из них правильный.
Чтобы объявить пустой фрагмент с нефиксированным размером, лучше сделать:
mySlice1 := make([]int, 0)
или:
mySlice2 := []int{}
Просто интересно, какой из них правильный.
Ответы:
Две альтернативы, которые вы дали, семантически идентичны, но использование make([]int, 0)
приведет к внутреннему вызову runtime.makeslice (Go 1.14).
У вас также есть возможность оставить его со nil
значением:
var myslice []int
Как написано в блоге Golang.org :
Нулевой срез функционально эквивалентен срезу нулевой длины, даже если он ничего не указывает. Он имеет нулевую длину и может быть добавлен с выделением.
Однако, nil
срез будет json.Marshal()
в "null"
то время как пустой срез будет "[]"
маршалировать, как указано @farwayer.
Ни один из вышеперечисленных параметров не приведет к выделению, как указывает @ArmanOrdookhani.
json.Marshal()
вернется null
за var myslice []int
и []
для инициализированного срезаmyslice := []int{}
reflect.DeepEqual
делает различие между нулевыми дольки и не-нулевыми ломтиков: a := []int{}
, var b []int
,reflect.DeepEqual(a, b) // returns false
Они эквивалентны. Смотрите этот код:
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
ноль ломтик
Они полезны, когда вы хотите представить фрагмент, который не существует, например, когда возникает исключение в функции, которая возвращает фрагмент.
// 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{}
Независимо от того, используете ли вы нулевой ломтик или пустой кусок, встроенные в функции
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
make
?
Пустой срез и нулевой срез инициализируются по-разному в 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.
make([]int, 0)
является лучшим, потому что Jetbrains GoLand не жалуется на то, что он «ненужен», как это имеет место в случае []int{}
. Это полезно при написании юнит-тестов.
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }