通过Go的内部函数mapclear方法删除。这个函数并没有显示的调用方法,当你使用for循环遍历删除所有元素时,Go的编译器会优化成Go内部函数mapclear。
<pre><code class="lang-go hljs"><span class="token keyword">package</span> main <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> m <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">byte</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">)</span> m<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span> m<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">2</span> <span class="token keyword">for</span> k <span class="token operator">:=</span> <span class="token keyword">range</span> m <span class="token punctuation">{</span> <span class="token function">delete</span><span class="token punctuation">(</span>m<span class="token punctuation">,</span> k<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>把上述源代码直接编译成汇编(默认编译是会优化的):
<pre><code class="lang-bash hljs">go tool compile -S map_clear.go </code></pre>可以看到编译器把源码9行的for循环直接优化成了mapclear去删除所有元素。如下:
再来看看关闭优化后的结果:
<pre><code class="lang-bash hljs">go tool compile -l -N -S map_clear.go </code></pre>关闭优化选项后,Go编译器直接通过循环遍历来删除map里面的元素。
具体的mapclear代码可以在go源码库中runtime/map.go文件中看到,代码如下:
<pre><code class="lang-go hljs"><span class="token comment">// mapclear deletes all keys from a map.</span> <span class="token keyword">func</span> <span class="token function">mapclear</span><span class="token punctuation">(</span>t <span class="token operator">*</span>maptype<span class="token punctuation">,</span> h <span class="token operator">*</span>hmap<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> raceenabled <span class="token operator">&&</span> h <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> callerpc <span class="token operator">:=</span> <span class="token function">getcallerpc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> pc <span class="token operator">:=</span> <span class="token function">funcPC</span><span class="token punctuation">(</span>mapclear<span class="token punctuation">)</span> <span class="token function">racewritepc</span><span class="token punctuation">(</span>unsafe<span class="token punctuation">.</span><span class="token function">Pointer</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span><span class="token punctuation">,</span> callerpc<span class="token punctuation">,</span> pc<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> h <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token operator">||</span> h<span class="token punctuation">.</span>count <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> h<span class="token punctuation">.</span>flags<span class="token operator">&</span>hashWriting <span class="token operator">!=</span> <span class="token number">0</span> <span class="token punctuation">{</span> <span class="token function">throw</span><span class="token punctuation">(</span><span class="token string">"concurrent map writes"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> h<span class="token punctuation">.</span>flags <span class="token operator">^=</span> hashWriting h<span class="token punctuation">.</span>flags <span class="token operator">&^=</span> sameSizeGrow h<span class="token punctuation">.</span>oldbuckets <span class="token operator">=</span> <span class="token boolean">nil</span> h<span class="token punctuation">.</span>nevacuate <span class="token operator">=</span> <span class="token number">0</span> h<span class="token punctuation">.</span>noverflow <span class="token operator">=</span> <span class="token number">0</span> h<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span> <span class="token comment">// Keep the mapextra allocation but clear any extra information.</span> <span class="token keyword">if</span> h<span class="token punctuation">.</span>extra <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token operator">*</span>h<span class="token punctuation">.</span>extra <span class="token operator">=</span> mapextra<span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// makeBucketArray clears the memory pointed to by h.buckets</span> <span class="token comment">// and recovers any overflow buckets by generating them</span> <span class="token comment">// as if h.buckets was newly alloced.</span> <span class="token boolean">_</span><span class="token punctuation">,</span> nextOverflow <span class="token operator">:=</span> <span class="token function">makeBucketArray</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> h<span class="token punctuation">.</span>B<span class="token punctuation">,</span> h<span class="token punctuation">.</span>buckets<span class="token punctuation">)</span> <span class="token keyword">if</span> nextOverflow <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token comment">// If overflow buckets are created then h.extra</span> <span class="token comment">// will have been allocated during initial bucket creation.</span> h<span class="token punctuation">.</span>extra<span class="token punctuation">.</span>nextOverflow <span class="token operator">=</span> nextOverflow <span class="token punctuation">}</span> <span class="token keyword">if</span> h<span class="token punctuation">.</span>flags<span class="token operator">&</span>hashWriting <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">{</span> <span class="token function">throw</span><span class="token punctuation">(</span><span class="token string">"concurrent map writes"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> h<span class="token punctuation">.</span>flags <span class="token operator">&^=</span> hashWriting <span class="token punctuation">}</span> </code></pre> <h2>