Вы говорите «нефиксированный размер», но срезы никогда не имеют фиксированного размера. Если вы не имеете в виду с нулевой емкостью. Обратите внимание, если у вас есть идея / предположение / подсказка о том, какая емкость вам может понадобиться, тогда лучше использовать версию с тремя аргументами. Например, чтобы построить кусок ключей карты:keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
Нулевой срез функционально эквивалентен срезу нулевой длины, даже если он ничего не указывает. Он имеет нулевую длину и может быть добавлен с выделением.
Однако, nilсрез будет json.Marshal()в "null"то время как пустой срез будет "[]"маршалировать, как указано @farwayer.
Ни один из вышеперечисленных параметров не приведет к выделению, как указывает @ArmanOrdookhani.
Также будьте осторожны: reflect.DeepEqualделает различие между нулевыми дольки и не-нулевыми ломтиков: a := []int{}, var b []int,reflect.DeepEqual(a, b) // returns false
asgaines
1
Почему вы думаете, что это сделает распределение? Цоколь равен нулю, поэтому ничего не выделяется. Все указатели на объекты нулевой длины указывают на одно и то же место в памяти: play.golang.org/p/MPOKKl_sYvw
Арман Ордухани
1
@ArmanOrdookhani Вы правы. Я попробовал это, и я также узнал, что был не прав с моим предположением об идентичных инструкциях по сборке. Исправлена!
Оба среза имеют 0емкость, которая подразумевает, что оба среза имеют 0длину (не может быть больше емкости), что означает, что оба среза не имеют элементов. Это означает, что 2 среза идентичны в каждом аспекте.
make([]int, 0)является лучшим, потому что Jetbrains GoLand не жалуется на то, что он «ненужен», как это имеет место в случае []int{}. Это полезно при написании юнит-тестов.
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
Ответы:
Две альтернативы, которые вы дали, семантически идентичны, но использование
make([]int, 0)
приведет к внутреннему вызову runtime.makeslice (Go 1.14).У вас также есть возможность оставить его со
nil
значением:Как написано в блоге 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
Они эквивалентны. Смотрите этот код:
Вывод:
Оба среза имеют
0
емкость, которая подразумевает, что оба среза имеют0
длину (не может быть больше емкости), что означает, что оба среза не имеют элементов. Это означает, что 2 среза идентичны в каждом аспекте.Смотрите похожие вопросы:
Какой смысл иметь нулевой ломтик и пустой ломтик в Голанге?
ноль ломтиков против не ноль ломтиков против пустых ломтиков на языке Go
источник
Как дополнение к ответу @ANisus ...
ниже приведена информация из книги « Действуй», о которой, я думаю, стоит упомянуть:
Разница между
nil
&empty
ломтикамиЕсли мы думаем о срезе, как это:
затем:
Пример игровой площадки :
печатает:
источник
make
?make
кажется, не возвращает адрес. Я считаю, что вы не можете сделать это за один шаг.Пустой срез и нулевой срез инициализируются по-разному в Go:
Что касается всех трех ломтиков, len и cap равны 0.
источник
make([]int, 0)
является лучшим, потому что Jetbrains GoLand не жалуется на то, что он «ненужен», как это имеет место в случае[]int{}
. Это полезно при написании юнит-тестов.