Vous dites "taille non fixe", mais les tranches n'ont jamais une taille fixe. Sauf si vous voulez dire avec une capacité nulle. Remarque, si vous avez une idée / une supposition / un indice de la capacité dont vous pourriez avoir besoin, l'utilisation de la version à trois arguments est bonne. Par exemple pour construire une tranche de clés de carte:keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
Les deux alternatives que vous avez données sont sémantiquement identiques, mais l'utilisation make([]int, 0)entraînera un appel interne à runtime.makeslice (Go 1.14).
Vous avez également la possibilité de le laisser avec une nilvaleur:
une tranche nulle est fonctionnellement équivalente à une tranche de longueur nulle, même si elle ne pointe vers rien. Il a une longueur nulle et peut être ajouté avec une allocation.
Une niltranche entrera cependant json.Marshal()dans "null"alors qu'une tranche vide entrera en "[]"mars, comme indiqué par @farwayer.
Aucune des options ci-dessus ne provoquera d'allocation, comme l'a souligné @ArmanOrdookhani.
Attention: json.Marshal()reviendra nullpour var myslice []intet []pour la tranche initialiséemyslice := []int{}
farwayer
10
Aussi soyez prudent: reflect.DeepEqualfait une distinction entre les tranches nil et tranches non nul: a := []int{}, var b []int,reflect.DeepEqual(a, b) // returns false
asgaines
1
Pourquoi pensez-vous qu'il ferait une allocation? Le plafond est nul, donc rien n'est alloué. Tous les pointeurs vers des objets de longueur nulle pointent vers le même emplacement en mémoire: play.golang.org/p/MPOKKl_sYvw
Arman Ordookhani
1
@ArmanOrdookhani Vous avez raison. Je l'ai essayé et j'ai également découvert que j'avais tort avec mon hypothèse sur des instructions de montage identiques. Fixé!
Les deux tranches ont une 0capacité, ce qui implique que les deux tranches ont une 0longueur (ne peut pas être supérieure à la capacité), ce qui implique que les deux tranches n'ont aucun élément. Cela signifie que les 2 tranches sont identiques dans tous les aspects.
Voici quelques informations du livre "Go in action" , qui, je pense, méritent d'être mentionnées:
Différence entre nil& emptytranches
Si nous pensons à une tranche comme celle-ci:
[pointer][length][capacity]
puis:
nil slice:[nil][0][0]
empty slice:[addr][0][0]// points to an address
tranche nulle
Ils sont utiles lorsque vous souhaitez représenter une tranche qui n'existe pas, par exemple lorsqu'une exception se produit dans une fonction qui renvoie une tranche.
// Create a nil slice of integers.var slice []int
tranche vide
Les tranches vides sont utiles lorsque vous souhaitez représenter une collection vide, par exemple lorsqu'une requête de base de données ne renvoie aucun résultat.
// 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{}
Peu importe si vous utilisez une tranche nulle ou une tranche vide, la fonctions intégrées append, lenet le captravail même.
Pouvons-nous obtenir l'adresse de la tranche vide en une seule étape en utilisant make?
Simin Jie
Si nous jetons un oeil à la signature de la fonction , makene semble pas retourner l'adresse. Je crois que vous ne pouvez pas le faire en une seule étape.
tgogos
13
La tranche vide et la tranche nulle sont initialisées différemment dans Go:
make([]int, 0)est le meilleur parce que Jetbrains GoLand ne se plaint pas qu'il soit "inutile" comme il le fait dans le cas de []int{}. Ceci est utile pour écrire des tests unitaires.
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
Réponses:
Les deux alternatives que vous avez données sont sémantiquement identiques, mais l'utilisation
make([]int, 0)
entraînera un appel interne à runtime.makeslice (Go 1.14).Vous avez également la possibilité de le laisser avec une
nil
valeur:Comme écrit sur le blog de Golang.org :
Une
nil
tranche entrera cependantjson.Marshal()
dans"null"
alors qu'une tranche vide entrera en"[]"
mars, comme indiqué par @farwayer.Aucune des options ci-dessus ne provoquera d'allocation, comme l'a souligné @ArmanOrdookhani.
la source
json.Marshal()
reviendranull
pourvar myslice []int
et[]
pour la tranche initialiséemyslice := []int{}
reflect.DeepEqual
fait une distinction entre les tranches nil et tranches non nul:a := []int{}
,var b []int
,reflect.DeepEqual(a, b) // returns false
Ils sont équivalents. Voir ce code:
Production:
Les deux tranches ont une
0
capacité, ce qui implique que les deux tranches ont une0
longueur (ne peut pas être supérieure à la capacité), ce qui implique que les deux tranches n'ont aucun élément. Cela signifie que les 2 tranches sont identiques dans tous les aspects.Voir des questions similaires:
Quel est l'intérêt d'avoir une tranche nulle et une tranche vide dans le golang?
tranches nulles vs tranches non nulles vs tranches vides en langue Go
la source
En complément de la réponse de @ANisus ...
Voici quelques informations du livre "Go in action" , qui, je pense, méritent d'être mentionnées:
Différence entre
nil
&empty
tranchesSi nous pensons à une tranche comme celle-ci:
puis:
Exemple de terrain de jeu :
impressions:
la source
make
?make
ne semble pas retourner l'adresse. Je crois que vous ne pouvez pas le faire en une seule étape.La tranche vide et la tranche nulle sont initialisées différemment dans Go:
Comme pour les trois tranches, len et cap sont à 0.
la source
make([]int, 0)
est le meilleur parce que Jetbrains GoLand ne se plaint pas qu'il soit "inutile" comme il le fait dans le cas de[]int{}
. Ceci est utile pour écrire des tests unitaires.