La réponse de Sebastian est exacte, mais je voulais savoir pourquoi c'était sûr, alors j'ai fouillé dans le code source de Map . Cela ressemble à un appel à delete(k, v)
, il définit simplement un indicateur (ainsi que la modification de la valeur de comptage) au lieu de supprimer réellement la valeur:
b->tophash[i] = Empty;
(Vide est une constante pour la valeur 0
)
Ce que la carte semble réellement faire est d'allouer un nombre défini de compartiments en fonction de la taille de la carte, qui augmente au fur et à mesure que vous effectuez des insertions au taux de 2^B
(à partir de ce code source ):
byte *buckets; // array of 2^B Buckets. may be nil if count==0.
Il y a donc presque toujours plus de buckets alloués que vous n'en utilisez, et lorsque vous effectuez un range
over the map, il vérifie la tophash
valeur de chaque bucket 2^B
pour voir s'il peut l'ignorer.
Pour résumer, delete
dans un range
est sûr parce que les données sont techniquement toujours là, mais quand il vérifie le, tophash
il voit qu'il peut simplement l'ignorer et ne pas l'inclure dans l' range
opération que vous effectuez. Le code source comprend même un TODO
:
// TODO: consolidate buckets if they are mostly empty
// can only consolidate if there are no live iterators at this size.
Cela explique pourquoi l'utilisation de la delete(k,v)
fonction ne libère pas réellement de mémoire, mais la supprime simplement de la liste des buckets auxquels vous êtes autorisé à accéder. Si vous souhaitez libérer de la mémoire réelle, vous devrez rendre la carte entière inaccessible afin que le garbage collection intervienne. Vous pouvez le faire en utilisant une ligne comme
map = nil