セバスチャンの答えは正確ですが、なぜそれが安全であるのか知りたいので、マップのソースコードを掘り下げました。の呼び出しのように見えますがdelete(k, v)
、実際に値を削除するのではなく、基本的にフラグを設定するだけでなく(カウント値を変更する):
b->tophash[i] = Empty;
(空は値の定数です0
)
マップが実際に実行しているように見えるのは、マップのサイズに応じて設定された数のバケットを割り当てることです。これは、2^B
(このソースコードから)の割合で挿入を実行すると増加します。
byte *buckets; // array of 2^B Buckets. may be nil if count==0.
したがって、割り当てられているバケットの数は、使用している数よりも多いことがほとんどです。range
マップ上でaを実行すると、その中tophash
の各バケットの値をチェックして、2^B
スキップできるかどうかを確認します。
要約delete
するrange
と、データは技術的にはまだ残っているので、内は安全ですが、チェックするtophash
と、スキップするだけで、range
実行中の操作に含めることができないことがわかります。ソースコードには以下も含まれますTODO
:
// TODO: consolidate buckets if they are mostly empty
// can only consolidate if there are no live iterators at this size.
これは、delete(k,v)
関数を使用しても実際にはメモリが解放されない理由を説明しています。アクセスを許可されているバケットのリストからそれを削除するだけです。実際のメモリを解放したい場合は、ガベージコレクションが実行されるように、マップ全体を到達不能にする必要があります。これは、次のような行を使用して実行できます。
map = nil