<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: arshia_rgh</title>
    <description>The latest articles on Forem by arshia_rgh (@arshiargh).</description>
    <link>https://forem.com/arshiargh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3489665%2F06e80187-19cd-46de-9fa9-30eb18a059ae.jpg</url>
      <title>Forem: arshia_rgh</title>
      <link>https://forem.com/arshiargh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/arshiargh"/>
    <language>en</language>
    <item>
      <title>🧩Golang Type Memory Representation Quick Reference</title>
      <dc:creator>arshia_rgh</dc:creator>
      <pubDate>Fri, 17 Oct 2025 12:04:15 +0000</pubDate>
      <link>https://forem.com/arshiargh/golang-type-memory-representation-quick-reference-321n</link>
      <guid>https://forem.com/arshiargh/golang-type-memory-representation-quick-reference-321n</guid>
      <description>&lt;p&gt;&lt;strong&gt;This article may be updated and improved later&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article provides a quick reference for Go types and their actual memory representation. Instead of focusing on syntax or usage, it explains what happens under the hood when you create a value of each type — how it is stored in memory, its internal structure, and its size on 32-bit and 64-bit architectures.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Pointer&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Memory address pointing to another value.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Memory:

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Note: A pointer can be &lt;code&gt;nil&lt;/code&gt;, meaning it points to nothing.&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;String&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Pointer to its underlying &lt;code&gt;Bytes&lt;/code&gt; + &lt;code&gt;len&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;StringHeader&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;
    &lt;span class="n"&gt;Len&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Memory: A pointer + int 

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 + 8 = 16 bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 + 4 = 8 bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Int, Float, complex(real + imaginary floats) or uint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If a numeric type is not explicitly sized (for example &lt;code&gt;int&lt;/code&gt; or &lt;code&gt;uint&lt;/code&gt;), its size depends on the architecture — 32-bit or 64-bit.&lt;/p&gt;

&lt;p&gt;If the type is explicitly sized (&lt;code&gt;int8&lt;/code&gt;, &lt;code&gt;int64&lt;/code&gt;, &lt;code&gt;complex64&lt;/code&gt;, etc.), its memory size matches the type name.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;int&lt;/code&gt; → 4 bytes on 32-bit, 8 bytes on 64-bit&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;complex64&lt;/code&gt; → 8 bytes (two float32 values)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Slice&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Pointer to its underlying &lt;code&gt;Bytes&lt;/code&gt; + &lt;code&gt;len&lt;/code&gt; + &lt;code&gt;cap&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;SliceHeader&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;
    &lt;span class="n"&gt;Len&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;Cap&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Memory:

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 + 8 + 8 = 24 bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 + 4 + 4 = 12 bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Note: Nillable. A &lt;code&gt;slice&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt; when its &lt;code&gt;data pointer&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt; and both &lt;code&gt;len&lt;/code&gt; and &lt;code&gt;cap&lt;/code&gt; are zero.&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Map&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Pointer to the struct &lt;code&gt;hmap&lt;/code&gt;(no_swiss) (&lt;code&gt;maps.Map&lt;/code&gt; for the swiss)&lt;/li&gt;
&lt;li&gt;Memory: 

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Note: Nillable (It is a Pointer)&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Chan&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Pointer to the struct &lt;code&gt;hchan&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Memory:

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Note: Nillable (It is a Pointer)&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Struct&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Inline layout of its fields. If it has no fields, it occupies zero bytes.&lt;/li&gt;
&lt;li&gt;Memory: Sum of field sizes + alignment padding. which are 8 bytes or 4 bytes ( based on the architecture)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="kt"&gt;int8&lt;/span&gt;   &lt;span class="c"&gt;// 1 byte&lt;/span&gt;
    &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;  &lt;span class="c"&gt;// 4 bytes&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the total size will be 8 bytes (on 64-bit) due to alignment padding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Example2&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="c"&gt;// 8 bytes&lt;/span&gt;
    &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;   &lt;span class="c"&gt;// 1 Bytes&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example2 will occupy 16 bytes on a 64-bit system.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Interface&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Two Pointers(&lt;code&gt;Type info pointer&lt;/code&gt; + &lt;code&gt;data pointer&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;EmptyInterface&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;NonEmptyInterface&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ITab&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ITab&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Memory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 + 8 = 16 Bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 + 4 = 8 Bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Note: Nillable. An interface is &lt;code&gt;nil&lt;/code&gt; when both its &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; pointers are &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Func&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is: Pointer to the function's code in memory.&lt;/li&gt;
&lt;li&gt;Memory:

&lt;ul&gt;
&lt;li&gt;64-bit -&amp;gt; 8 Bytes&lt;/li&gt;
&lt;li&gt;32-bit -&amp;gt; 4 Bytes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Note: Nillable, (It is a Pointer).&lt;/li&gt;

&lt;/ul&gt;




&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Size (64-bit)&lt;/th&gt;
&lt;th&gt;Size (32-bit)&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Boolean&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;Represents &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. May include padding in structs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integer (Signed)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;8-bit signed integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16-bit signed integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;32-bit signed integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;64-bit signed integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Machine word-sized integer (depends on architecture).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integer (Unsigned)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;8-bit unsigned integer (alias: &lt;code&gt;byte&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16-bit unsigned integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;32-bit unsigned integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;64-bit unsigned integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Machine word-sized unsigned integer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uintptr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Unsigned integer large enough to store a pointer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Text Types&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Struct: pointer to data + length (&lt;code&gt;Data uintptr&lt;/code&gt;, &lt;code&gt;Len int&lt;/code&gt;). Immutable.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rune&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Alias for &lt;code&gt;int32&lt;/code&gt;, represents a Unicode code point.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;byte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Alias for &lt;code&gt;uint8&lt;/code&gt;, represents a raw byte.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Floating Point&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;float32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;32-bit IEEE 754 floating-point number.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;float64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;64-bit IEEE 754 floating-point number.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complex Numbers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;complex64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Two &lt;code&gt;float32&lt;/code&gt; values: real + imaginary (4 + 4).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;complex128&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Two &lt;code&gt;float64&lt;/code&gt; values: real + imaginary (8 + 8).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Composite Types&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;varies&lt;/td&gt;
&lt;td&gt;varies&lt;/td&gt;
&lt;td&gt;Fixed-length, contiguous block of elements. Value type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;slice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Struct: pointer + length + capacity (&lt;code&gt;Data uintptr&lt;/code&gt;, &lt;code&gt;Len int&lt;/code&gt;, &lt;code&gt;Cap int&lt;/code&gt;). Reference type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;struct&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;varies&lt;/td&gt;
&lt;td&gt;varies&lt;/td&gt;
&lt;td&gt;Inline fields + alignment padding. Value type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Pointer to &lt;code&gt;runtime.hmap&lt;/code&gt; (hash table). Reference type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chan&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Pointer to &lt;code&gt;runtime.hchan&lt;/code&gt; (channel buffer &amp;amp; state). Reference type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;interface&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Struct: type info pointer + data pointer (&lt;code&gt;itab*&lt;/code&gt;, &lt;code&gt;data unsafe.Pointer&lt;/code&gt;). Reference type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pointer&lt;/code&gt; (&lt;code&gt;*T&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Direct memory address pointing to value of type &lt;code&gt;T&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;function&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Pointer to it's code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Special Types&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nil&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Zero value for reference types. No memory allocation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unsafe / Runtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unsafe.Pointer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Untyped pointer; can convert to/from &lt;code&gt;uintptr&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Empty Struct&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;struct{}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Takes no space; used for signals or markers.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>types</category>
      <category>byte</category>
    </item>
    <item>
      <title>🛠️ Golang Source Code Essentials, Part 1: The unsafe Package — Breaking Go’s Safety for Power</title>
      <dc:creator>arshia_rgh</dc:creator>
      <pubDate>Tue, 14 Oct 2025 14:15:50 +0000</pubDate>
      <link>https://forem.com/arshiargh/golang-source-code-essentials-part-1-unsafe-and-internal-packages-unsafe-sys-atomic-3apg</link>
      <guid>https://forem.com/arshiargh/golang-source-code-essentials-part-1-unsafe-and-internal-packages-unsafe-sys-atomic-3apg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Go is a &lt;strong&gt;statically typed language&lt;/strong&gt;, which means type safety is checked and enforced at compile time. The compiler makes sure you can’t mix up types or misuse values, that’s one of the reasons Go programs are so stable and reliable.&lt;br&gt;
But Go also has a small, dangerous, and extremely powerful back door called the &lt;code&gt;unsafe&lt;/code&gt; package.&lt;br&gt;
This package lets you step outside the type system and talk directly to memory, no safety checks, no compiler protection. It exists mainly for the Go runtime itself, but developers can use it too, at their own risk.&lt;br&gt;&lt;br&gt;
When you use &lt;code&gt;unsafe&lt;/code&gt;, you’re saying, “I know what I’m doing,” and if you’re wrong, the crash (or silent corruption) is on you. In return, you get access to things like raw pointers, custom memory layouts, and performance tricks that would otherwise be impossible in pure Go.&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similar concepts exist in other statically typed languages such as &lt;strong&gt;Java&lt;/strong&gt; (via &lt;code&gt;sun.misc.Unsafe&lt;/code&gt;) and &lt;strong&gt;Rust&lt;/strong&gt; (with its &lt;code&gt;unsafe&lt;/code&gt; blocks). They all serve the same purpose — to give developers a way to break safety rules when they absolutely need to, usually for performance or low-level operations like system calls and pointer manipulation.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;By the end of this article, you’ll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Why the runtime needs the &lt;code&gt;unsafe&lt;/code&gt; package&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What the &lt;code&gt;unsafe&lt;/code&gt; package really provides&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How it allows you to reinterpret memory and manipulate addresses&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to use it safely and what &lt;code&gt;uintptr&lt;/code&gt; actually is&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Where &lt;code&gt;unsafe&lt;/code&gt; lives in Go’s source code and how it’s implemented&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;And finally, how to do some fun (and slightly dangerous 😄) things using unsafe&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;⚙️ Why the Runtime Needs &lt;code&gt;Unsafe&lt;/code&gt; Power&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At first glance, Go looks like the kind of language that would never need something like &lt;code&gt;unsafe&lt;/code&gt;.It’s memory-safe, garbage-collected, and statically typed, three things that usually keep you far away from raw memory operations.&lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So why does the Go runtime rely so heavily on it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The answer is simple: because safety itself requires control.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The runtime, the layer that manages goroutines, memory allocation, garbage collection, and scheduling, sits closer to the hardware than any other part of Go. It can’t build itself using only the safe abstractions that ordinary Go code depends on, because those abstractions depend on the runtime(classic chicken-and-egg problem😅).To create and manage the safety guarantees that the rest of the language enjoys, the runtime sometimes has to step outside those guarantees. That’s where &lt;code&gt;unsafe&lt;/code&gt; comes in.&lt;/p&gt;

&lt;p&gt;Here are a few concrete examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Memory layout control – The runtime needs to know exactly how structs, slices, and objects are arranged in memory to implement the garbage collector and scheduler efficiently. Go’s regular reflection APIs aren’t low-level enough for that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Direct pointer manipulation: When the runtime needs to link objects in memory (like connecting goroutine stacks or marking heap objects), it can’t afford the overhead or indirection of safe pointer conversions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interacting with CPU or OS boundaries: Certain operations, such as reading atomic counters or interacting with system-specific memory regions, require direct access to raw addresses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance-critical code: In parts of the runtime that run constantly — like garbage collection or goroutine scheduling — every nanosecond matters. Eliminating even a small layer of abstraction can make a big difference.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all these cases, unsafe acts as the bridge between Go’s managed world and the machine’s raw memory. It’s what allows the runtime to bend the rules temporarily so that those same rules can be enforced safely everywhere else.You can think of it like the runtime reaching beneath the language’s safety net to make sure the net itself doesn’t tear.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of course, this power comes with serious responsibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When something goes wrong inside the runtime, a bad pointer conversion, a misaligned atomic operation, or an incorrect memory assumption, the entire Go process can crash instantly. That’s why unsafe and other internal packages are tightly restricted to the runtime and standard library. They exist to make Go possible, not for day-to-day application development.&lt;/p&gt;

&lt;p&gt;But it’s important to note that the unsafe package isn’t hidden or private, it’s part of Go’s public standard library, and that’s intentional.&lt;br&gt;
The Go team designed it this way so that developers could still use it in rare cases where direct memory access or type manipulation is absolutely necessary.&lt;br&gt;
Many real-world projects already rely on unsafe for performance-critical or low-level work (as discussed in &lt;a href="https://arxiv.org/pdf/2006.09973" rel="noopener noreferrer"&gt;this research&lt;/a&gt; )&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;🧠 Core Functions and Types in the &lt;code&gt;unsafe&lt;/code&gt; Package&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;unsafe&lt;/code&gt; package is one of the smallest in the Go standard library, yet it’s also one of the most powerful and dangerous.&lt;br&gt;
It doesn’t import anything, it doesn’t depend on the runtime, and it contains only a handful of functions and types. But those few tools give you direct access to the raw memory that Go normally protects you from.&lt;br&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;🧩 The Core Types&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are only two key types in &lt;code&gt;unsafe&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;unsafe.Pointer&lt;/code&gt;&lt;/strong&gt;: a special kind of pointer that can point to anything.
It’s not tied to any specific type, and Go lets you convert between unsafe.Pointer and other pointer types freely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3.14&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we’re reinterpreting the memory of a &lt;code&gt;float64&lt;/code&gt; as a &lt;code&gt;uint64&lt;/code&gt;,       just reading the same bits differently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;uintptr&lt;/code&gt;&lt;/strong&gt; — an integer large enough to hold a pointer value(8 byte or 4 byte ...).
It’s used when you need to perform arithmetic on addresses (for example, offsetting a pointer manually).
But unlike unsafe.Pointer, a uintptr doesn’t keep the memory alive, the garbage collector treats it as a number, not a reference.
So converting between them requires caution:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;aPtr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;aPtr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first case, the GC knows there’s a pointer to &lt;code&gt;a&lt;/code&gt;, so it won’t collect it, But in the second case, &lt;code&gt;aPtr&lt;/code&gt; is just an integer — &lt;code&gt;a&lt;/code&gt; can be garbage collected.&lt;br&gt;
As the Go documentation warns, you should not store a &lt;code&gt;uintptr&lt;/code&gt; in a variable and use it later.&lt;br&gt;
Instead, use it directly, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;⚖️ The Utility Functions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;unsafe&lt;/code&gt; also includes a few key functions that reveal how Go’s runtime lays things out in memory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Sizeof(x)&lt;/code&gt; → returns the size in bytes of the value x.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Alignof(x)&lt;/code&gt; → tells you the alignment requirements of a variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Offsetof(x)&lt;/code&gt; → gives you the byte offset of a struct field.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, these functions let you understand and control how Go arranges your data in memory.&lt;/p&gt;

&lt;p&gt;New APIs in the newer Go versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Add(ptr, len)&lt;/code&gt; → adds len to the ptr and returns the updated ptr&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Slice(ptr, len)&lt;/code&gt; → returns a slice that underlying array starts at ptr and len and cap is the len argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SliceData(slice)&lt;/code&gt; → returns the ptr to the underlying array of the slice argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;String(ptr, len)&lt;/code&gt; → returns a string that underlying bytes starts at ptr and length is the len argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StringData(string)&lt;/code&gt; → returns a ptr to the underlying bytes of the string argument&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🕵️‍♂️ Where Does unsafe Actually Live?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxaqzwthdv41az062hp2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxaqzwthdv41az062hp2.png" alt="unsafe" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
If you explore the Go source code, you’ll find the &lt;code&gt;unsafe&lt;/code&gt; package in the root of the &lt;code&gt;src&lt;/code&gt; directory. Inside it, there’s only one file — &lt;code&gt;unsafe.go&lt;/code&gt; — and its content (as of Go 1.25.0) looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ArbitraryType&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;IntegerType&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Pointer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ArbitraryType&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;ArbitraryType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;ArbitraryType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Alignof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;ArbitraryType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt; &lt;span class="n"&gt;IntegerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Pointer&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ArbitraryType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt; &lt;span class="n"&gt;IntegerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;ArbitraryType&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SliceData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;ArbitraryType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ArbitraryType&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt; &lt;span class="n"&gt;IntegerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;StringData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So… where are the implementations? 🤔&lt;br&gt;
There’s no &lt;code&gt;.s&lt;/code&gt; (Go assembly) file in the unsafe directory, and no &lt;code&gt;//go:linkname&lt;/code&gt; directives either.&lt;br&gt;
How does Go even make this work if there’s no implementation file or linker trick? (check &lt;a href="https://dev.to/arshiargh/golang-source-code-essentials-part-0-compiler-directives-build-tags-4j74"&gt;here&lt;/a&gt; if you don't know what I am talking about)&lt;/p&gt;

&lt;p&gt;The answer is: &lt;code&gt;unsafe&lt;/code&gt; &lt;strong&gt;is special to the compiler&lt;/strong&gt;.&lt;br&gt;
It has hardcoded logic that recognizes the &lt;code&gt;unsafe&lt;/code&gt; package and its functions.&lt;br&gt;
When the compiler sees calls like &lt;code&gt;unsafe.Sizeof()&lt;/code&gt;, it doesn’t look for an implementation — it directly generates the corresponding code itself.&lt;/p&gt;

&lt;p&gt;In other words, the compiler contains special-case logic such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If this is unsafe.Sizeof, compute the size at compile time.”&lt;br&gt;
“If this is unsafe.Pointer, treat it as a type conversion.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These functions are &lt;strong&gt;compiler intrinsics&lt;/strong&gt; — they don’t execute at runtime, they’re evaluated during compilation.&lt;/p&gt;

&lt;p&gt;For example, inside &lt;code&gt;src/cmd/compile/internal/typecheck/universe.go&lt;/code&gt;, you can see how the &lt;code&gt;unsafe&lt;/code&gt; functions are registered alongside the built-in functions (&lt;code&gt;len&lt;/code&gt;, &lt;code&gt;recover&lt;/code&gt;, &lt;code&gt;new&lt;/code&gt;, &lt;code&gt;panic&lt;/code&gt;, etc.) and other predeclared names in Go (&lt;code&gt;_&lt;/code&gt;, &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;nil&lt;/code&gt;, and so on).&lt;br&gt;
It is done by calling the function, called &lt;code&gt;NewBuiltin&lt;/code&gt;(for the functions), which is documented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// NewBuiltin returns a new Name representing a builtin function,&lt;/span&gt;
&lt;span class="c"&gt;// either predeclared or from package unsafe.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the compiler knows exactly what each of these functions means — not because they’re implemented in Go or assembly, but because they’re &lt;strong&gt;baked directly into the compiler itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For more information about it, you may check:&lt;br&gt;
&lt;code&gt;cmd/compile/internal/ssagen/ssa.go&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cmd/compile/internal/typecheck/universe.go&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cmd/compile/internal/ir/name.go&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;😈 Fun with &lt;code&gt;unsafe&lt;/code&gt;: Dangerous but Cool&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I love playing with &lt;code&gt;unsafe&lt;/code&gt;. It helps me understand Go’s memory model better — and honestly, it’s just fun. Sometimes it even leads to real-world performance optimizations that are impossible with normal Go code.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;unsafe&lt;/code&gt; package is fascinating in every language, but I especially enjoy how &lt;strong&gt;Rust&lt;/strong&gt; handles it — its &lt;code&gt;unsafe&lt;/code&gt; blocks let you do things like &lt;code&gt;memory unions&lt;/code&gt;, where two variables can share the exact same memory space(like &lt;strong&gt;C/C++&lt;/strong&gt;), something that is not possible in Go &lt;a href="https://dave.cheney.net/2017/04/29/there-is-no-pass-by-reference-in-go" rel="noopener noreferrer"&gt;as Dave Cheney explained&lt;/a&gt;, but &lt;code&gt;unsafe&lt;/code&gt; still gives us plenty of ways to peek behind the curtain.&lt;/p&gt;

&lt;p&gt;Some fun and useful experiments you can try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the fields of a struct by manually moving the Pointer&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explore built-in Go types and peek inside their internals (like inspecting the buckets of a map)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or some common optimizations like convert &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;bytes&lt;/code&gt;, which normally cause allocation, but with &lt;code&gt;unsafe&lt;/code&gt;, you can do it without triggering  any allocations&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see some examples:&lt;/p&gt;
&lt;h3&gt;
  
  
  1- Accessing the fields of a struct with &lt;code&gt;unsafe&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Car&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BMW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2023&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cPTR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;cPTR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Name:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Year:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2024&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"updated car"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;name := *(*string)(cPTR)&lt;/code&gt; we are saying that the &lt;code&gt;cPTR&lt;/code&gt; is actually &lt;code&gt;*string&lt;/code&gt; and then dereference it with &lt;code&gt;*&lt;/code&gt;, so it is not something really hard, it is just a simple type cast for &lt;code&gt;unsafe.Pointer&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Structs&lt;/code&gt; in Go are nothing but their fields, so when we take the &lt;code&gt;unsafe.Pointer&lt;/code&gt; of the struct, we are already pointing at the first field.&lt;/li&gt;
&lt;li&gt;Each type has a size, &lt;a href="https://dev.to/arshiargh/golang-type-memory-representation-quick-reference-321n"&gt;read here&lt;/a&gt;, but for structs, it’s safer to use &lt;code&gt;unsafe.Offsetof()&lt;/code&gt; because of potential padding.&lt;/li&gt;
&lt;li&gt;In this example, we could skip &lt;code&gt;unsafe.Offsetof()&lt;/code&gt; since the layout is predictable on a 64-bit system: the &lt;code&gt;string&lt;/code&gt; takes 16 bytes (two machine words), and the &lt;code&gt;int&lt;/code&gt; takes 8 bytes, so there’s no padding - meaning we could do with just 16 instead of &lt;code&gt;unsafe.Offsetof(Car{}.year)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2- Explore the builtin Go types
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"s"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"rr"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"rr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;yPTR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;yPTR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;uint8&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;yPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmap&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;uint8&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;yPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmap&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;bucketsPTR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;yPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmap&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;oldBucketsPTR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;yPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offsetof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmap&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oldbuckets&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"flags:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"buckets:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bucketsPTR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"oldbuckets:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oldBucketsPTR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"count:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketsPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketsPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;key2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketsPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;value2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucketsPTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;56&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"changed"&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;key2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A little simplified version of &lt;code&gt;hmap&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;hmap&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt; 
    &lt;span class="n"&gt;flags&lt;/span&gt;     &lt;span class="kt"&gt;uint8&lt;/span&gt;
    &lt;span class="n"&gt;B&lt;/span&gt;         &lt;span class="kt"&gt;uint8&lt;/span&gt;  
    &lt;span class="n"&gt;noverflow&lt;/span&gt; &lt;span class="kt"&gt;uint16&lt;/span&gt; 
    &lt;span class="n"&gt;hash0&lt;/span&gt;     &lt;span class="kt"&gt;uint32&lt;/span&gt; 

    &lt;span class="n"&gt;buckets&lt;/span&gt;    &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt; 
    &lt;span class="n"&gt;oldbuckets&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt; 
    &lt;span class="n"&gt;nevacuate&lt;/span&gt;  &lt;span class="kt"&gt;uintptr&lt;/span&gt;        
    &lt;span class="n"&gt;clearSeq&lt;/span&gt;   &lt;span class="kt"&gt;uint64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are exploring Maps here (no_swiss).&lt;/li&gt;
&lt;li&gt;Maps are pointers to the &lt;code&gt;hmap&lt;/code&gt; struct, so in the line &lt;code&gt;yPTR := (*unsafe.Pointer)(unsafe.Pointer(&amp;amp;y))&lt;/code&gt; we are telling that the &lt;code&gt;yPTR&lt;/code&gt; is actually a pointer to the &lt;code&gt;unsafe.Pointer&lt;/code&gt;, because the &lt;code&gt;y&lt;/code&gt; is a pointer itself and the &lt;code&gt;&amp;amp;y&lt;/code&gt; is something like a pointer-to-pointer.&lt;/li&gt;
&lt;li&gt;In line &lt;code&gt;count := *(*int64)(*yPTR)&lt;/code&gt; we are already at the field count.&lt;/li&gt;
&lt;li&gt;We move until we get to the &lt;code&gt;buckets&lt;/code&gt; where the data is actually stored.&lt;/li&gt;
&lt;li&gt;Each Bucket has a &lt;code&gt;tophash&lt;/code&gt; that helps it search faster (it filters candidate buckets before comparing keys), the &lt;code&gt;tophash&lt;/code&gt; is &lt;code&gt;[8]uint8&lt;/code&gt;, so to reach the first key we should &lt;code&gt;key := unsafe.Add(bucketsPTR, 8)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Each &lt;code&gt;string&lt;/code&gt; is 16bytes, so for the first value we should move (8+16)24bytes and same for others.&lt;/li&gt;
&lt;li&gt;As you see, we can also edit the map, and we can also do other funny things like accessing the old buckets to see the overflows and more, maybe change the map to the threshold and see what is going on in the buckets, discussed about it &lt;a href="https://dev.to/arshiargh/go-maps-deep-dive-part-1-the-secrets-behind-o1-performance-overflows-and-growth-227"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I suggest you do the same things with the &lt;code&gt;channels&lt;/code&gt;, there you can access the goroutines and many more fun things.&lt;/p&gt;

&lt;h3&gt;
  
  
  3- A common simple optimization is to convert &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;bytes&lt;/code&gt;, which has one allocation normally
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;stringTest&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;

    &lt;span class="n"&gt;stringTestByte&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;stringTest&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringTestByte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c"&gt;// Same output as the next line&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stringTest&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// But this version allocates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As &lt;a href="https://dev.to/arshiargh/golang-type-memory-representation-quick-reference-321n"&gt;explained here&lt;/a&gt;, &lt;code&gt;strings&lt;/code&gt; are pointers to underlying &lt;code&gt;bytes&lt;/code&gt; + &lt;code&gt;len&lt;/code&gt;, so when we take the &lt;code&gt;unsafe.Pointer&lt;/code&gt; of the string, in the &lt;code&gt;StringHeader&lt;/code&gt; struct we are actually pointing at the first field, which is the underlying &lt;code&gt;bytes&lt;/code&gt; ( here you can move 8 more and get the &lt;code&gt;len&lt;/code&gt;, I know you are the best at doing these now 😉)&lt;/p&gt;







&lt;p&gt;The &lt;code&gt;unsafe&lt;/code&gt; package is both powerful and risky — a bit like playing with fire 🔥. It’s great for learning, debugging, squeezing out performance, and some low-level codes — but keep it out of production code unless you really know what you’re doing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just remember: with &lt;code&gt;unsafe&lt;/code&gt;, you’re responsible for safety now.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>go</category>
      <category>tutorial</category>
      <category>unsafe</category>
    </item>
    <item>
      <title>🛠️Golang Source Code Essentials, Part 0: Compiler Directives &amp; Build Tags⚡</title>
      <dc:creator>arshia_rgh</dc:creator>
      <pubDate>Thu, 25 Sep 2025 21:41:25 +0000</pubDate>
      <link>https://forem.com/arshiargh/golang-source-code-essentials-part-0-compiler-directives-build-tags-4j74</link>
      <guid>https://forem.com/arshiargh/golang-source-code-essentials-part-0-compiler-directives-build-tags-4j74</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;After the &lt;a href="https://dev.to/arshiargh/go-maps-deep-dive-part-1-the-secrets-behind-o1-performance-overflows-and-growth-227"&gt;Go Maps Deep Dive (no_swiss) — Part 1&lt;/a&gt;, the natural next step is to explore Go’s source code itself and see how these functionalities are actually implemented under the hood.&lt;/p&gt;

&lt;p&gt;But before we can dive into files like &lt;code&gt;map.go&lt;/code&gt; or &lt;code&gt;map_swiss.go&lt;/code&gt;, we need to equip ourselves with some background knowledge. The Go runtime makes heavy use of compiler directives, unsafe operations, bit tricks, and even bits of assembly. Without understanding these essentials, the source code can feel cryptic.&lt;/p&gt;

&lt;p&gt;That’s why I’m starting this new series: &lt;strong&gt;Golang Source Code Essentials&lt;/strong&gt;. This series will serve as a foundation, teaching the tools and concepts you’ll repeatedly encounter when reading Go’s internals. Once we cover these, we’ll return to maps (and beyond!) with the confidence to truly understand what’s happening in the runtime.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡Compiler directives (&lt;code&gt;//go:linkname&lt;/code&gt;, &lt;code&gt;//go:nosplit&lt;/code&gt;, &lt;code&gt;build tags&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;🔒&lt;code&gt;Unsafe&lt;/code&gt; and how to use&lt;/li&gt;
&lt;li&gt;🔢&lt;strong&gt;Bit operations&lt;/strong&gt; and low-level optimizations commonly used in the runtime&lt;/li&gt;
&lt;li&gt;🧩Assembly touchpoints (&lt;code&gt;memmove&lt;/code&gt;, &lt;code&gt;memclrNoHeapPointers&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;📏Stack growth and garbage collector interactions (why &lt;code&gt;nosplit&lt;/code&gt; matters)&lt;/li&gt;
&lt;li&gt;🧭Practical tips on navigating, modifying, and rebuilding the Go source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of this series, you’ll be comfortable opening Go’s runtime files and actually understanding what’s happening.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For part 0, we start with &lt;strong&gt;Compiler Directives and Build tags&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Line Directives (&lt;code&gt;//line&lt;/code&gt;)&lt;/strong&gt;📝:
&lt;/h2&gt;

&lt;p&gt;Mainly used by code generators and tools to improve error reporting, it tells the compiler to treat the following code as if it comes from a different line number and/or file.&lt;/p&gt;

&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//line main.go:100&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, regardless of the actual file or line, the compiler output will look like::&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;main.go:100: invalid operation: &lt;span class="s2"&gt;"test"&lt;/span&gt; + 123 &lt;span class="o"&gt;(&lt;/span&gt;mismatched types untyped string and untyped int&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Function Directives&lt;/strong&gt;⚙️:
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. //go:noescape:
&lt;/h2&gt;

&lt;p&gt;It tells the compiler that the function does not allow any of its pointer arguments to escape to the heap. This can help the compiler optimize stack allocation and calling conventions. It is mainly used in low-level or runtime code, and has no effect on the function's behavior—just on how the compiler treats pointer arguments.&lt;/p&gt;

&lt;p&gt;It must be followed by a function declaration without a body, and the &lt;code&gt;.s&lt;/code&gt; assembly file must exist in the same package; otherwise, the code won’t compile.&lt;/p&gt;

&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:noescape&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is valid if there is the &lt;code&gt;.s&lt;/code&gt; file (Go assembly source file, we will talk about these in the next parts) and the actual implementation of the &lt;code&gt;test1&lt;/code&gt; is inside that &lt;code&gt;.s&lt;/code&gt; file with the exact same name, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//go:build amd64

#include "textflag.h"

// TEXT ·test1(SB), NOSPLIT, $0-16
// Implements: func test1(a unsafe.Pointer) unsafe.Pointer
TEXT ·test1(SB), NOSPLIT, $0-16
    MOVQ 0(FP), AX      // load a
    MOVQ AX, 8(FP)      // store return value
    RET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the first line you can see that &lt;code&gt;//go:build amd64&lt;/code&gt;, this is a build constraint. It tells the Go build system to compile that file only when targeting the &lt;code&gt;amd64&lt;/code&gt; architecture, If the file name already ends with &lt;code&gt;_amd64.s&lt;/code&gt;, the build tag is optional&lt;/p&gt;

&lt;p&gt;if we don't have any &lt;code&gt;.s&lt;/code&gt; files in the same package and run the above code we will get the error: &lt;code&gt;missing function body&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As I mentioned, functions marked with &lt;code&gt;//go:noescape&lt;/code&gt; must not have a body.&lt;/p&gt;

&lt;p&gt;we put a &lt;code&gt;.s&lt;/code&gt; file and run the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//line main.go:100&lt;/span&gt;
&lt;span class="c"&gt;//var x = "test" + 123&lt;/span&gt;

&lt;span class="c"&gt;//go:noescape&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;

&lt;span class="c"&gt;//go:noescape&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;test2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;main.go:106: can only use //go:noescape with external func implementations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;( Have you noticed the &lt;code&gt;main.go:106&lt;/code&gt;!!!?, Very cool, isn't it?!🤩 )&lt;/p&gt;

&lt;h2&gt;
  
  
  2. //go:noinline🚫:
&lt;/h2&gt;

&lt;p&gt;It must be followed by a function declaration, telling the compiler to never inline the immediately following function, regardless of size or heuristics. It is used mainly for writing stable benchmarks (preventing the optimizer from removing or folding calls) or debugging the compiler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:noinline&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. //go:nosplit🧵:
&lt;/h2&gt;

&lt;p&gt;It must be followed by a function declaration, disables stack growth checks for the immediately following function. The compiler omits the stack-splitting prologue, so the function must never need more stack than is already available ( no call to &lt;code&gt;morestack&lt;/code&gt; ). Used in tiny, leaf, low-level runtime functions that must run even when the goroutine stack is almost exhausted (e.g. during &lt;code&gt;stack growth&lt;/code&gt;, &lt;code&gt;signal handling&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Note&lt;/code&gt;: We will discuss this further in later parts.&lt;/p&gt;

&lt;p&gt;Constraints: keep it very small, do not call into code that might allocate, panic, block, or grow the stack. Misuse can cause unrecoverable crashes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:nosplit&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;load8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;uint8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Must stay tiny: just one load.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;uint8&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crash example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:nosplit&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I called it with &lt;code&gt;n = 1000&lt;/code&gt; and the output was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;main.add: nosplit stack over 792 byte limit
main.add&amp;lt;1&amp;gt;
    grows 24 bytes, calls main.add&amp;lt;1&amp;gt;
    infinite cycle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Linkname Directives(&lt;code&gt;//go:linkname&lt;/code&gt;)&lt;/strong&gt;🔗:
&lt;/h2&gt;

&lt;p&gt;It tells the compiler that a local identifier should be bound to (share the symbol of) some other (possibly unexported) identifier in another package. &lt;/p&gt;

&lt;p&gt;It bypasses visibility, is inherently unsafe and  version‑fragile.&lt;/p&gt;

&lt;p&gt;It requires importing the &lt;code&gt;unsafe&lt;/code&gt; package, even if unused &lt;code&gt;(e.g. import _ "unsafe")&lt;/code&gt;, because the Go team specifically tell us that this is unsafe&lt;/p&gt;

&lt;p&gt;The two functions that are linked together don’t need to have the same signature, leading to panics if misused&lt;/p&gt;

&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="c"&gt;// inside the main.go file:&lt;/span&gt;

&lt;span class="c"&gt;//go:linkname testLink&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;testLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;// inside the test.go file in another package named 'another':&lt;/span&gt;
&lt;span class="c"&gt;//go:linkname test main.testLink&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be "ab". As you can see, the &lt;code&gt;test&lt;/code&gt; function in the &lt;code&gt;another&lt;/code&gt; package is private (not exported), and the signatures also don’t match.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Linkname: Dangerous Freedom⚠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The linkname directive created a problem: we can easily write functions or variables that link to Go’s internals, and this made many dependencies on the Golang internals, this has created a serious problem: many programs now depend on Go’s internal details, something they were never meant to rely on, because changing the internals may break those Go programs as well, The Go team is trying to lock down (or at least limit) the usage of linkname in user code to avoid more dependencies on the Golang internals, and currently Go team has a &lt;code&gt;hall of shame&lt;/code&gt; that includes some most known programs that are already dependent on these internals for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Call from Go to C.&lt;/span&gt;
&lt;span class="c"&gt;//&lt;/span&gt;
&lt;span class="c"&gt;// This must be nosplit because it's used for syscalls on some&lt;/span&gt;
&lt;span class="c"&gt;// platforms. Syscalls may have untyped arguments on the stack, so&lt;/span&gt;
&lt;span class="c"&gt;// it's not safe to grow or scan the stack.&lt;/span&gt;
&lt;span class="c"&gt;//&lt;/span&gt;
&lt;span class="c"&gt;// cgocall should be an internal detail,&lt;/span&gt;
&lt;span class="c"&gt;// but widely used packages access it using linkname.&lt;/span&gt;
&lt;span class="c"&gt;// Notable members of the hall of shame include:&lt;/span&gt;
&lt;span class="c"&gt;//   - github.com/ebitengine/purego&lt;/span&gt;
&lt;span class="c"&gt;//&lt;/span&gt;
&lt;span class="c"&gt;// Do not remove or change the type signature.&lt;/span&gt;
&lt;span class="c"&gt;// See go.dev/issue/67401.&lt;/span&gt;
&lt;span class="c"&gt;//&lt;/span&gt;
&lt;span class="c"&gt;//go:linkname cgocall&lt;/span&gt;
&lt;span class="c"&gt;//go:nosplit&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;cgocall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, there is documentation for this function inside cgocall.go file inside the runtime package and includes a &lt;code&gt;Notable members of the hall of shame&lt;/code&gt; list.&lt;/p&gt;

&lt;p&gt;I strongly recommend reading the &lt;a href="https://github.com/golang/go/issues/67401" rel="noopener noreferrer"&gt;Russ Cox issue in Golang GitHub page: cmd/link: lock down future uses of linkname #67401&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Build Tags (&lt;code&gt;//go:build&lt;/code&gt;, &lt;code&gt;// +build&lt;/code&gt;)&lt;/strong&gt;🏗️:
&lt;/h2&gt;

&lt;p&gt;Build tags determine whether a file should be included in the compilation of a package. This is incredibly useful for writing platform-specific code or creating different build versions of your application.&lt;/p&gt;

&lt;p&gt;The modern and preferred syntax is the &lt;code&gt;//go:build&lt;/code&gt; directive. It must be placed at the top of the file, preceded only by blank lines or other comments, and must be followed by a blank line.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;//go:build&lt;/code&gt; (Go 1.17+)&lt;/strong&gt;
This means compile this file only when building for Linux on amd64:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build linux &amp;amp;&amp;amp; amd64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means compile this file only on &lt;code&gt;64-bit Linux&lt;/code&gt; or &lt;code&gt;64-bit Windows&lt;/code&gt; systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build (linux &amp;amp;&amp;amp; amd64) || (windows &amp;amp;&amp;amp; amd64)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Custom Tags🏷️&lt;/strong&gt;: You can define your own tags to create different builds, like a "development" build with extra logging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build dev&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;mypackage&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"log"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;DebugLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[DEV] %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build !dev&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;mypackage&lt;/span&gt;

&lt;span class="c"&gt;// This is a no-op in release builds.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;DebugLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To compile with the dev tag, you use the &lt;code&gt;-tags&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This will include debug_logger.go and its DebugLog implementation.&lt;/span&gt;
go build &lt;span class="nt"&gt;-tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"dev"&lt;/span&gt;

&lt;span class="c"&gt;# This will include release_logger.go, where DebugLog does nothing.&lt;/span&gt;
go build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;// +build&lt;/code&gt; (Legacy)&lt;/strong&gt;
This is the older syntax. While still supported, &lt;code&gt;//go:build&lt;/code&gt; is preferred. You can use both in the same file for backward compatibility. A file is included if the boolean formula is satisfied.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// +build linux,darwin&lt;/span&gt;
&lt;span class="c"&gt;// ... this file will be included on Linux OR Darwin systems.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀&lt;strong&gt;What’s Next?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this part, we explored compiler directives and build tags, the “hidden switches” that control how Go source files are compiled and how runtime functions behave. These are everywhere in the Go runtime and now you’ll recognize them when diving into files like &lt;code&gt;runtime/asm_amd64.s&lt;/code&gt; or &lt;code&gt;map.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 In Part 1, we’ll dive into the Unsafe &amp;amp; Internal Packages that the runtime depends on. You’ll see how &lt;code&gt;unsafe.Pointer&lt;/code&gt;, &lt;code&gt;runtime/internal/sys&lt;/code&gt;, and &lt;code&gt;runtime/internal/atomic&lt;/code&gt; unlock the low-level power behind Go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay tuned — it’s about to get even more interesting! ⚡&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>compiler</category>
    </item>
    <item>
      <title>🗺️ Go Maps Deep Dive (no_swiss) — Part 1: The Secrets Behind O(1) Performance, Overflows, and Growth</title>
      <dc:creator>arshia_rgh</dc:creator>
      <pubDate>Wed, 17 Sep 2025 11:23:16 +0000</pubDate>
      <link>https://forem.com/arshiargh/go-maps-deep-dive-part-1-the-secrets-behind-o1-performance-overflows-and-growth-227</link>
      <guid>https://forem.com/arshiargh/go-maps-deep-dive-part-1-the-secrets-behind-o1-performance-overflows-and-growth-227</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;strong&gt;This article focuses on the old Go map implementation (map_noswiss). In later parts of this series, we will also cover the Swiss map (map_swiss).&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Welcome back to our deep dive into Go maps! 👋 In the &lt;a href="https://dev.to/arshiargh/go-maps-deep-dive-part-0-understanding-the-basics-3pjc"&gt;first part of this series&lt;/a&gt;, we covered the basics of what Go maps are, their properties, and how to use them. Now, it's time to go deeper and uncover the magic that makes maps so efficient. 🗺️✨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we'll explore the inner workings of Go maps to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why map operations are &lt;em&gt;usually&lt;/em&gt; O(1) and what can affect this performance. ⏱️&lt;/li&gt;
&lt;li&gt;How Go handles hash collisions with "overflow" buckets. 📦➡️📦&lt;/li&gt;
&lt;li&gt;The clever way maps grow without bringing your application to a halt. 🌱&lt;/li&gt;
&lt;li&gt;The role of a unique "seed" in the hashing process. 🎲&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  The O(1) Magic: It's All About Hashing
&lt;/h3&gt;

&lt;p&gt;You've probably heard that map lookups, insertions, and deletions are O(1) operations, meaning they take constant time on average, regardless of the number of elements in the map. But how is this possible? The secret lies in &lt;strong&gt;hashing&lt;/strong&gt;. 🔑➡️🔢&lt;/p&gt;

&lt;p&gt;When you add a key-value pair to a map, Go uses a hash function to convert the key into a number. This number, or "hash," is then used to determine which "bucket" the key-value pair should be stored in. A bucket is essentially a small, fixed-size array that can hold a few key-value pairs.&lt;/p&gt;

&lt;p&gt;Because the hash function is designed to be very fast and to distribute keys evenly across the available buckets, Go can quickly locate the correct bucket for a given key without having to check every element in the map. This is what gives maps their O(1) performance. 💪&lt;/p&gt;

&lt;p&gt;However, I said &lt;em&gt;usually&lt;/em&gt; O(1). What happens when two different keys generate the same hash? This is called a &lt;strong&gt;hash collision&lt;/strong&gt;, and it can slightly degrade performance. We'll explore this more in the section on overflows. 💥&lt;/p&gt;

&lt;h3&gt;
  
  
  The Unique Seed: Why the Same Key Can Live in Different Places
&lt;/h3&gt;

&lt;p&gt;Here's a fun fact that might surprise you: if you create two different maps and insert the same key into both, that key might end up in different buckets in each map. 🤯&lt;/p&gt;

&lt;p&gt;Why? Because every new map in Go is created with a &lt;strong&gt;unique random seed&lt;/strong&gt;. This seed is used in the hashing algorithm, which means that the hash generated for a key is unique to that specific map instance.&lt;/p&gt;

&lt;p&gt;Let's look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;map1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;map2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;map1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;map2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

    &lt;span class="c"&gt;// The internal location of "a" in map1 and map2&lt;/span&gt;
    &lt;span class="c"&gt;// will likely be different!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This randomization is a security feature that helps prevent a type of attack called "hash-flooding," where an attacker could craft keys that all hash to the same bucket, effectively turning the map's O(1) operations into O(n) and slowing down your application. 🛡️&lt;/p&gt;

&lt;h2&gt;
  
  
  When Buckets Get Full: The Role of Overflows
&lt;/h2&gt;

&lt;p&gt;Each bucket in a Go map can hold up to 8 key-value pairs. But what happens when more than 8 keys hash to the same bucket? Go doesn't just give up. Instead, it creates an overflow bucket and links it to the original bucket. 🔗&lt;/p&gt;

&lt;p&gt;A simplified visualization of a hash table bucket with an overflow bucket attached, showing keys spilling into the overflow when the primary bucket is full.&lt;/p&gt;

&lt;p&gt;If you have many keys that hash to the same bucket, you can end up with a chain of overflow buckets. When looking up a key in this scenario, Go first checks the main bucket and then has to traverse the chain of overflow buckets. This is one of the reasons why map operations are not always O(1). In the worst-case scenario (many collisions), a lookup could degrade to O(n) performance, where 'n' is the number of items in the bucket and its overflows. 🐢&lt;/p&gt;

&lt;h2&gt;
  
  
  The Growing Map: An Incremental Approach
&lt;/h2&gt;

&lt;p&gt;As you add more and more elements to a map, it will eventually need to grow to accommodate the new data and maintain its performance. A map in Go will trigger a growth cycle in one of two situations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The load factor is too high&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the average number of elements per bucket exceeds a certain threshold (currently around 6.5), the map will grow. 📈&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Too many overflow buckets&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the map has too many overflow buckets, it's a sign that the keys are not well-distributed, and a resize is needed to spread them out more evenly. 🧹&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But how does this growth happen? If you have a map with thousands or even millions of key-value pairs, resizing it all at once could cause a noticeable pause in your application. To avoid this, Go employs a clever strategy: incremental growth. 🚀&lt;/p&gt;

&lt;p&gt;When a map needs to grow, Go allocates a new, larger array of buckets (usually double the size of the old one). However, it doesn't copy all the data over at once. Instead, the copying happens gradually. Each time you write to or delete from the map, Go moves a few buckets from the old array to the new one. ➡️➡️➡️&lt;/p&gt;

&lt;p&gt;This incremental approach spreads the work of resizing over time, ensuring that no single map operation takes too long. It's a fantastic example of how Go is designed for building responsive, low-latency applications. 💖&lt;/p&gt;

&lt;h2&gt;
  
  
  🗝️About the hint in make(map[K]V, hint)
&lt;/h2&gt;

&lt;p&gt;When you write something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the second argument (13 in this case) is not the length, size, or capacity of the map. It is just a hint to the runtime about how many elements you expect to insert.&lt;/p&gt;

&lt;p&gt;Go maps use buckets internally, and the runtime uses the hint to decide how many buckets to preallocate. Each bucket can hold up to 8 key/value pairs. Go tries to keep the average load factor around 6.5 elements per bucket before growing.&lt;/p&gt;

&lt;p&gt;For example, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;With a hint of 13, the runtime will start with 2 buckets (capacity for 16 slots). Since 13 / 2 = 6.5, this is right at the threshold.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the hint were 14, the runtime would start with 4 buckets (capacity for 32 slots). That’s because 14 / 2 = 7 would exceed the load factor limit, so it doubles the bucket count.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why the hint value causes jumps in allocation instead of scaling smoothly.&lt;/p&gt;

&lt;p&gt;take a look at this table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hint Range&lt;/th&gt;
&lt;th&gt;Bucket Count&lt;/th&gt;
&lt;th&gt;Capacity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0 – 8&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9 – 13&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14 – 26&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27 – 52&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;53 – 104&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;105 – 208&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;209 – 416&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;417 – 832&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;833 – 1664&lt;/td&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;We've covered a lot of ground in this article, from hashing and overflows to the incremental growth of maps. I hope you now have a better appreciation for the sophisticated engineering that makes Go maps so powerful and efficient. 🧠💡&lt;/p&gt;

&lt;p&gt;But we're not done yet! In the next part of this series, we'll get our hands dirty and dive into the Go source code to see exactly how all of these concepts are implemented. It's going to be a fun and enlightening journey, so stay tuned! 💻🔍&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>maps</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🗺️ Go Maps Deep Dive — Part 0: Understanding the Basics</title>
      <dc:creator>arshia_rgh</dc:creator>
      <pubDate>Tue, 09 Sep 2025 14:23:18 +0000</pubDate>
      <link>https://forem.com/arshiargh/go-maps-deep-dive-part-0-understanding-the-basics-3pjc</link>
      <guid>https://forem.com/arshiargh/go-maps-deep-dive-part-0-understanding-the-basics-3pjc</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;strong&gt;Most of the details in this article apply to both the old and new Go map implementations (&lt;em&gt;map_noswiss&lt;/em&gt; and &lt;em&gt;map_swiss&lt;/em&gt;). However, when I refer to a map as a pointer to hmap, that specifically applies to the old implementation (map_noswiss). In later parts of this series, we will also cover the Swiss maps.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Series Intro:
&lt;/h2&gt;

&lt;p&gt;Welcome to the start of my Go maps deep-dive series!&lt;br&gt;
In the upcoming parts, we’ll go &lt;strong&gt;from the outer layer of maps to their deep internals — how they’re implemented under the hood, memory layout, hash functions, optimizations, and performance tricks&lt;/strong&gt;.&lt;br&gt;
This is Part 0, where we’ll start from the basics: what maps are, how they behave, and what you should know before diving deeper.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧩 What Are Maps?
&lt;/h2&gt;

&lt;p&gt;In Go, a map is a key-value data structure.&lt;br&gt;
If you’ve used Rust, you know it as a &lt;strong&gt;HashMap&lt;/strong&gt;.&lt;br&gt;
If you’ve used Python, you know it as a dict.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c"&gt;// 5&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They’re unordered collections of key-value pairs, designed for fast lookups and inserts.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗝️ Maps Are Pointers
&lt;/h2&gt;

&lt;p&gt;Unlike slices, maps in Go are internally pointers to a data structure called &lt;strong&gt;hmap&lt;/strong&gt;.&lt;br&gt;
This has two important consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t need to pass them by pointer.&lt;/li&gt;
&lt;li&gt;When you pass a map to a function, you’re already passing a pointer under the hood. ( in old versions you were used to do like *map[int]int but changed) see &lt;a href="https://groups.google.com/g/golang-nuts/c/SjuhSYDITm4/m/jnrp7rRxDQAJ" rel="noopener noreferrer"&gt;Lan Taylor&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In the very early days what we call maps now were written as pointers, so you wrote *map[int]int. We moved away from that when we realized that no one ever wrote &lt;code&gt;map&lt;/code&gt; without writing &lt;code&gt;*map&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The zero value is nil.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;if you declare a map and then assign it to the new value the both m1, and m2 will be placed in unique memory locations (see blog by dave chenny &lt;a href="https://dave.cheney.net/2017/04/29/there-is-no-pass-by-reference-in-go" rel="noopener noreferrer"&gt;There is no pass-by-reference in Go&lt;/a&gt;) and them value both will be the address of a same hmap structure. &lt;/li&gt;
&lt;li&gt;Actually the m1 will be cpoied to the m2 (like all assigns in Golang)&lt;/li&gt;
&lt;li&gt;Updating m2 also updates m1.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp5hl7f3d7who02s7ero.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp5hl7f3d7who02s7ero.webp" alt="Go map pointer diagram" width="800" height="673"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;em&gt;Diagram: &lt;code&gt;m1&lt;/code&gt; and &lt;code&gt;m2&lt;/code&gt; point to the same underlying &lt;code&gt;hmap&lt;/code&gt; struct&lt;/em&gt; ( picture by VictoriaMetrics )&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚖️ Maps Are Not Comparable
&lt;/h2&gt;

&lt;p&gt;Unlike slices, you cannot compare two maps directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c"&gt;// This will not compile ❌&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c"&gt;// This will not compile too ❌&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c"&gt;// But you *can* check if a map is nil ✅&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"m1 is nil"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔑 Keys Must Be Comparable
&lt;/h2&gt;

&lt;p&gt;The type you use as a key must be comparable in Go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Valid keys:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;int&lt;/strong&gt;, &lt;strong&gt;float64&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;struct&lt;/strong&gt; (if all fields are comparable)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Invalid keys:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;slice&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;map&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;function&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;interface{} or any can be sometimes ok sometimes nok&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="c"&gt;// OK✅&lt;/span&gt;

&lt;span class="n"&gt;x2&lt;/span&gt;&lt;span class="p"&gt;[[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="c"&gt;//runtime panic!❌&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⏱️ Lookup and Insert Are Usually O(1)
&lt;/h2&gt;

&lt;p&gt;Go maps are hash-based, so operations like searching and inserting are on average &lt;strong&gt;O(1)&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why “usually” O(1)?&lt;/strong&gt;&lt;br&gt;
In upcoming parts, we’ll explore hash collisions, buckets, and why performance can sometimes degrade. Stay tuned! 👀&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ⚡ Maps Are Not Thread-Safe
&lt;/h2&gt;

&lt;p&gt;Go maps are not safe for concurrent writes.&lt;br&gt;
If you try, you’ll get a fatal runtime error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt; &lt;span class="p"&gt;}()&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;84&lt;/span&gt; &lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;💥 Runtime panic&lt;/strong&gt;: concurrent map writes&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ Creating Maps with make
&lt;/h2&gt;

&lt;p&gt;You can create maps with &lt;strong&gt;make&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;m := make(map[int]int, 10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Here, the 10 is not the length — it’s a &lt;strong&gt;hint&lt;/strong&gt; to Go about the expected size.&lt;br&gt;
This helps reduce resizing overhead when inserting many items.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We’ll talk about why it’s just a hint and how Go actually allocates buckets in a future part.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔜 What’s Next?
&lt;/h2&gt;

&lt;p&gt;This is just the beginning! In Part 1, we’ll start peeling back the layers of the hmap structure — the backbone of Go maps.&lt;br&gt;
We’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The internal hmap struct&lt;/li&gt;
&lt;li&gt;Buckets and hashing&lt;/li&gt;
&lt;li&gt;Load factors and resizing strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and after all parts you will have good sight about what happening exactly inside the go internals for maps&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay tuned — things are about to get really interesting! 🚀&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>hashmap</category>
      <category>map</category>
    </item>
  </channel>
</rss>
