<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ pointers - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ pointers - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 23 Jun 2026 22:44:56 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/pointers/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Learn How to Use Pointers in Go – With Example Code ]]>
                </title>
                <description>
                    <![CDATA[ Pointers are a fundamental but often dreaded concept in every programming language that supports them. Luckily for us, Go makes working with pointers straightforward and safe. In this article, we will demystify pointers in Go. You'll learn: What poi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-how-to-use-pointers-in-go-with-example-code/</link>
                <guid isPermaLink="false">68e3da89c573b56a3f251e06</guid>
                
                    <category>
                        <![CDATA[ Go Language ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pointers ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gabor Koos ]]>
                </dc:creator>
                <pubDate>Mon, 06 Oct 2025 15:04:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759763060124/8b3f21fa-052e-4c18-a1b4-9fe4fd456830.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Pointers are a fundamental but often dreaded concept in every programming language that supports them. Luckily for us, Go makes working with pointers straightforward and safe.</p>
<p>In this article, we will demystify pointers in Go. You'll learn:</p>
<ul>
<li><p>What pointers are and how to use them</p>
</li>
<li><p>How to declare pointers and dereference them</p>
</li>
<li><p>Common pitfalls, like nil pointers and reference types</p>
</li>
<li><p>Pointer receivers in structs (a key reason pointers are so useful in Go)</p>
</li>
<li><p>A bonus look at weak pointers (Go 1.24+) for advanced memory management</p>
</li>
</ul>
<p>By the end, you'll have a solid understanding of pointers and be confident using them in your own Go programs.</p>
<h2 id="heading-what-well-cover">What We’ll Cover:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-pointer">What is a Pointer?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-understanding-memory">Understanding Memory</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-stack-vs-heap">Stack vs Heap</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-pointer">The Pointer</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-declaring-and-using-pointers">Declaring and Using Pointers</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-pointers-to-basic-types">Pointers to Basic Types</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-getting-an-address-with-amp">Getting an Address with &amp;</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-pointers-to-structs">Pointers to Structs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-pointers-to-other-user-types">Pointers to Other User Types</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-why-use-pointers">Why Use Pointers?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-avoiding-copies">Avoiding Copies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-sharing-and-mutating-state">Sharing and Mutating State</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-method-receivers">Method Receivers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-interfacing-with-low-level-apis">Interfacing with Low-Level APIs</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-common-pitfalls-and-misunderstandings">Common Pitfalls and Misunderstandings</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-nil-pointers">Nil Pointers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-reference-types">Reference Types</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-pointer-receivers">Pointer Receivers</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-value-receivers-vs-pointer-receivers">Value Receivers vs Pointer Receivers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-idiomatic-go">Idiomatic Go</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-exercises-for-the-reader">Exercises for the Reader</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-bonus-weak-pointers-go-124">Bonus: Weak Pointers (Go 1.24+)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-are-weak-pointers">What Are Weak Pointers?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-when-to-use-weak-pointers">When to Use Weak Pointers?</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-summary-amp-best-practices">Summary &amp; Best Practices</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solutions-to-exercises">Solutions to Exercises</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>This article assumes you have a basic understanding of Go, including:</p>
<ul>
<li><p>Variables and basic types (<code>int</code>, <code>string</code>, and so on)</p>
</li>
<li><p>Functions and function calls</p>
</li>
<li><p>Structs and methods</p>
</li>
</ul>
<p>Familiarity with memory concepts (like copying vs referencing values) can be helpful, but it is not required. I’ll explain all examples in a beginner-friendly way.</p>
<h2 id="heading-what-is-a-pointer">What is a Pointer?</h2>
<h3 id="heading-understanding-memory">Understanding Memory</h3>
<p>Memory in a computer is a large sequence of bytes, each with a unique address. Every variable in a program occupies one or more contiguous bytes in memory, depending on its type:</p>
<ul>
<li><p>An <code>int32</code> typically occupies 4 bytes.</p>
</li>
<li><p>An <code>int64</code> typically occupies 8 bytes.</p>
</li>
<li><p>A <code>bool</code> usually occupies 1 byte.</p>
</li>
</ul>
<p>Structs, arrays, and slices occupy the sum of their fields' sizes, plus potential padding for alignment (for quick access). Each variable has a unique memory address, which is where its data is stored.</p>
<p>For example, consider:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> a <span class="hljs-keyword">int32</span> = <span class="hljs-number">100</span>
<span class="hljs-keyword">var</span> b <span class="hljs-keyword">bool</span> = <span class="hljs-literal">true</span>
</code></pre>
<p>This will look something like this in memory:</p>
<p><img src="https://i.ibb.co/B2jZ3Smc/memory.png" alt="Memory Layout" width="311" height="301" loading="lazy"></p>
<p><code>a</code> occupies 4 bytes and holds the value <code>100</code>. <code>b</code> occupies 1 byte and holds <code>true</code>. A variable's address is simply the location in memory where its data starts (0×02022 for <code>a</code>, and 0x0207 for <code>b</code> in this example).</p>
<h3 id="heading-stack-vs-heap">Stack vs Heap</h3>
<p>In Go, variables can be allocated on the <strong>stack</strong> or the <strong>heap</strong>. The stack is a region of memory that stores local variables and function call information. It’s fast to allocate and deallocate, as it works in a last-in-first-out manner.</p>
<p>The heap is a larger pool of memory used for dynamic allocation. Variables allocated on the heap can outlive the function that created them, making them suitable for data that needs to be shared or modified across different parts of a program.</p>
<p>The Go runtime automatically manages memory allocation and garbage collection, so you don't need to worry about manually freeing memory like in some other languages.</p>
<p>The stack and heap are just implementation details. As a Go programmer, you typically don't need to worry about where a variable is allocated. The Go compiler and runtime handle this for you. You definitely don't have to worry about it in this article – just know they exist and that pointers can point to values in either location.</p>
<h3 id="heading-the-pointer">The Pointer</h3>
<p>A pointer is simply a variable that <strong>stores the memory address of another variable</strong>. From the diagram above, you can see that an address is basically an integer value (which happens to represent a location in memory). On a 64-bit system, addresses are typically 8 bytes (64 bits) long, so a pointer variable will also occupy 8 bytes.</p>
<p>In Go, you declare a pointer using the <code>*</code> operator. Pointers also have a <strong>type</strong>, which is the type of the variable they point to. For example:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> p *<span class="hljs-keyword">int32</span> <span class="hljs-comment">// a pointer to an int32</span>
</code></pre>
<p>You can get the address of a variable using the <code>&amp;</code> operator:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> a <span class="hljs-keyword">int32</span> = <span class="hljs-number">100</span>
<span class="hljs-keyword">var</span> p *<span class="hljs-keyword">int32</span> = &amp;a <span class="hljs-comment">// p now holds the address of a</span>
</code></pre>
<p>In memory:</p>
<p><img src="https://i.ibb.co/4ZGzs3Rz/pointer.png" alt="Pointer Example" width="348" height="481" loading="lazy"></p>
<p><code>a</code> holds the value <code>100</code> at address <code>0x0202</code>. <code>p</code> holds the address of <code>a</code> (<code>0x0202</code>), and <code>p</code> itself is stored at its own address (<code>0x0207</code>).</p>
<p>The reason pointers carry type information is that you can <strong>dereference</strong> them: follow the address to access the underlying value. This is also done using the <code>*</code> operator:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> a <span class="hljs-keyword">int32</span> = <span class="hljs-number">100</span>
<span class="hljs-keyword">var</span> p *<span class="hljs-keyword">int32</span> = &amp;a <span class="hljs-comment">// p now holds the address of a</span>

fmt.Println(*p) <span class="hljs-comment">// prints the value at the address p points to, which is the value of a: 100</span>
</code></pre>
<p>This dual use of <code>*</code> is a common source of confusion, so let's clarify:</p>
<ol>
<li><p>In a <em>type declaration</em> (like <code>var p *int32</code>), <code>*</code> indicates that <code>p</code> is a pointer to an <code>int32</code>.</p>
</li>
<li><p>In an <em>expression</em> (like <code>*p</code>), <code>*</code> dereferences the pointer, giving you access to the value it points to.</p>
</li>
</ol>
<p>Next, let's break down how to declare and use pointers in practice, so you can see how <code>&amp;</code> and <code>*</code> work together.</p>
<h2 id="heading-declaring-and-using-pointers">Declaring and Using Pointers</h2>
<p>Now that we know what pointers are conceptually, let's see how they look in real Go code.</p>
<h3 id="heading-pointers-to-basic-types">Pointers to Basic Types</h3>
<p>As we saw earlier, you can declare a pointer variable with the <code>*</code> operator in the type:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> p *<span class="hljs-keyword">int</span>      <span class="hljs-comment">// p is a pointer to an int, but currently nil</span>
fmt.Println(p)  <span class="hljs-comment">// &lt;nil&gt;</span>
</code></pre>
<p>Like every variable in Go, if you don't initialize it, it defaults to the zero value for its type. For pointers, the zero value is <code>nil</code>, meaning it doesn't point to any valid memory address.</p>
<p>You can also use the built-in <code>new</code> function to allocate a value and get its pointer:</p>
<pre><code class="lang-go">p := <span class="hljs-built_in">new</span>(<span class="hljs-keyword">int</span>)  <span class="hljs-comment">// p is a pointer to an int with a zero value (0 for int)</span>
fmt.Println(*p) <span class="hljs-comment">// prints 0, the zero value for int</span>
</code></pre>
<h3 id="heading-getting-an-address-with-amp">Getting an Address with <code>&amp;</code></h3>
<p>The <code>&amp;</code> operator retrieves the address of an existing variable:</p>
<pre><code class="lang-go">x := <span class="hljs-number">42</span>
p := &amp;x <span class="hljs-comment">// p now holds the address of x</span>

fmt.Println(*p) <span class="hljs-comment">// 42</span>
*p = <span class="hljs-number">99</span>         <span class="hljs-comment">// change the value at the address p points to (which is x)</span>
fmt.Println(x)  <span class="hljs-comment">// 99</span>
fmt.Println(p)  <span class="hljs-comment">// prints the memory address of x, e.g., 0xc0000140b8</span>
fmt.Println(&amp;x) <span class="hljs-comment">// prints the same address as p</span>
</code></pre>
<h3 id="heading-pointers-to-structs">Pointers to Structs</h3>
<p>Pointers can point to any type. They are especially common with <strong>structs</strong>:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
    Name <span class="hljs-keyword">string</span>
    Age  <span class="hljs-keyword">int</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    u := User{<span class="hljs-string">"Alice"</span>, <span class="hljs-number">30</span>}
    p := &amp;u                 <span class="hljs-comment">// pointer to User</span>
    fmt.Println((*p).Age)   <span class="hljs-comment">// 30</span>
    fmt.Println(p.Name)     <span class="hljs-comment">// Alice - shorthand for (*p).Name</span>
}
</code></pre>
<p>You can access fields with either <code>(*p).Name</code> or simply <code>p.Name</code>. Go <strong>automatically dereferences struct pointers</strong> for convenience.</p>
<p>We'll explore struct pointers more in the "Pointer Receivers" section.</p>
<h3 id="heading-pointers-to-other-user-types">Pointers to Other User Types</h3>
<p>You can create pointers to any named type:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Point <span class="hljs-keyword">struct</span> {
    X, Y <span class="hljs-keyword">int</span>
}
p := &amp;Point{X: <span class="hljs-number">1</span>, Y: <span class="hljs-number">2</span>} <span class="hljs-comment">// pointer to Point</span>
fmt.Println(p.X, p.Y)   <span class="hljs-comment">// 1 2 - shorthand for (*p).X and (*p).Y</span>
</code></pre>
<p>The syntax works exactly the same for user-defined types as it does for built-ins.</p>
<h2 id="heading-why-use-pointers">Why Use Pointers?</h2>
<p>At first glance, pointers may look like mental gymnastics. Why not just use values directly? Here are some key reasons to use pointers in Go:</p>
<h3 id="heading-avoiding-copies">Avoiding Copies</h3>
<p>When you assign a value in Go, it's copied:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
    Name <span class="hljs-keyword">string</span>
    Age  <span class="hljs-keyword">int</span>
}

u1 := User{<span class="hljs-string">"Alice"</span>, <span class="hljs-number">30</span>}
u2 := u1  <span class="hljs-comment">// copy</span>
u2.Age = <span class="hljs-number">40</span>

fmt.Println(u1.Age) <span class="hljs-comment">// 30</span>
fmt.Println(u2.Age) <span class="hljs-comment">// 40</span>
</code></pre>
<p>When the struct is small with just a few fields (like this example), copying is cheap. But if it's large (hundreds of fields or nested data), copying can be inefficient. Passing a pointer avoids making a full copy:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Birthday</span><span class="hljs-params">(u *User)</span></span> {
    u.Age++
}

u := User{<span class="hljs-string">"Bob"</span>, <span class="hljs-number">29</span>}
Birthday(&amp;u)
fmt.Println(u.Age) <span class="hljs-comment">// 30</span>
</code></pre>
<h3 id="heading-sharing-and-mutating-state">Sharing and Mutating State</h3>
<p>Sometimes you want multiple parts of your program to work with the same object. With values, each assignment makes a copy:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Counter <span class="hljs-keyword">struct</span> {
    value <span class="hljs-keyword">int32</span>
}

c1 := Counter{value: <span class="hljs-number">0</span>} <span class="hljs-comment">// c1 is a Counter</span>
c2 := c1  <span class="hljs-comment">// c2 is a copy - another Counter</span>

c2.value++
fmt.Println(c1.value) <span class="hljs-comment">// 0</span>
fmt.Println(c2.value) <span class="hljs-comment">// 1</span>
</code></pre>
<p>Using pointers ensures both variables refer to the same underlying data:</p>
<pre><code class="lang-go">pc1 := &amp;Counter{value: <span class="hljs-number">0</span>} <span class="hljs-comment">// pc1 is a pointer to a Counter</span>
pc2 := pc1   <span class="hljs-comment">// copy of the pointer - both point to the same Counter</span>

pc2.value++
fmt.Println(pc1.value) <span class="hljs-comment">// 1</span>
fmt.Println(pc2.value) <span class="hljs-comment">// 1</span>
</code></pre>
<p>This diagram illustrates the two memory layouts:</p>
<p><img src="https://i.ibb.co/tPXSr9FN/counter.png" alt="Value vs Pointer" width="977" height="541" loading="lazy"></p>
<p><code>c1</code> and <code>c2</code> are stored separately at <code>0x0202</code> and <code>0x0207</code>, each with its own 4-byte <code>value</code> field. In the second example, <code>pc1</code> and <code>pc2</code> are stored at <code>0x0202</code> and <code>0x020a</code> respectively, and both hold the same address (<code>0x1002</code>) pointing to a single <code>Counter</code> instance in the heap, having its own 4-byte <code>value</code> field.</p>
<h3 id="heading-method-receivers">Method Receivers</h3>
<p>Go methods can have <strong>value receivers</strong> or <strong>pointer receivers</strong>. Pointer receivers are needed when:</p>
<ul>
<li><p>The method should modify the struct</p>
</li>
<li><p>The struct is large and copying would be costly</p>
</li>
<li><p>You want consistency (it's common to make all receivers pointers if some need to be)</p>
</li>
</ul>
<p>We'll cover this in detail in the "Pointer Receivers" section.</p>
<h3 id="heading-interfacing-with-low-level-apis">Interfacing with Low-Level APIs</h3>
<p>Some libraries and system calls require you to pass memory addresses, not copies. Pointers make this possible, while still being type-safe in Go.</p>
<h2 id="heading-common-pitfalls-and-misunderstandings">Common Pitfalls and Misunderstandings</h2>
<h3 id="heading-nil-pointers">Nil Pointers</h3>
<p>If you declare a pointer without initializing it, it will be <code>nil</code>. Dereferencing a nil pointer will immediately cause a runtime panic:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> p *<span class="hljs-keyword">int</span>
fmt.Println(*p) <span class="hljs-comment">// panic: runtime error: invalid memory address or nil pointer dereference</span>
</code></pre>
<p>This is Go's way of telling you that you tried to follow an address that doesn't exist. To safely use pointers, you always need to give them a valid target before dereferencing:</p>
<pre><code class="lang-go">x := <span class="hljs-number">42</span>
p := &amp;x          <span class="hljs-comment">// p points to x</span>
fmt.Println(*p)  <span class="hljs-comment">// 42</span>

q := <span class="hljs-built_in">new</span>(<span class="hljs-keyword">int</span>)    <span class="hljs-comment">// allocates memory for an int, initializes it to 0</span>
fmt.Println(*q)  <span class="hljs-comment">// 0</span>
</code></pre>
<p>Both <code>&amp;</code> and <code>new</code> ensure that the pointer points to valid memory.</p>
<h3 id="heading-reference-types">Reference Types</h3>
<p>In Go, everything is passed by value. But this value depends on the <strong>inner representation</strong> of the type. For example, a slice is stored in memory as:</p>
<pre><code class="lang-go"><span class="hljs-keyword">struct</span> {
    ptr *ElementType <span class="hljs-comment">// pointer to the underlying array</span>
    <span class="hljs-built_in">len</span> <span class="hljs-keyword">int</span>          <span class="hljs-comment">// length of the slice</span>
    <span class="hljs-built_in">cap</span> <span class="hljs-keyword">int</span>          <span class="hljs-comment">// capacity of the slice</span>
}
</code></pre>
<p>When you pass a slice to a function, you are passing a copy of this struct. The <code>ptr</code> field still points to the same underlying array, so changes to the elements of the slice inside the function will affect the original slice.</p>
<p>Because of this behavior, slices are often referred to as <strong>reference types</strong>: you don’t need to use pointers with them to share or mutate data. Other reference types in Go include maps and channels. Strings are also considered reference types, but they are immutable, so you cannot change their contents.</p>
<p>Note that pointers themselves are not reference types: they are simply variables that hold memory addresses.</p>
<p>(To complicate things a bit further, if you pass a slice to a function and then re-slice it or append to it, you are modifying the copy of the slice struct. The original slice outside the function will not see these changes!)</p>
<h2 id="heading-pointer-receivers">Pointer Receivers</h2>
<p>When defining methods on structs in Go, you can choose between value receivers and pointer receivers. Understanding the difference is key to writing correct and efficient Go code.</p>
<h3 id="heading-value-receivers-vs-pointer-receivers">Value Receivers vs Pointer Receivers</h3>
<p><strong>Value receiver</strong>: the method gets a copy of the struct. Any modifications inside the method do not affect the original struct.</p>
<p><strong>Pointer receiver</strong>: the method gets a copy of the pointer, which still points to the original struct. Modifications inside the method affect the original struct.</p>
<p>Example:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Counter <span class="hljs-keyword">struct</span> {
    value <span class="hljs-keyword">int</span>
}
</code></pre>
<p>If you try to increment the counter using a value receiver, it won't work as expected:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c Counter)</span> <span class="hljs-title">Inc</span><span class="hljs-params">()</span></span> {
    c.value++ <span class="hljs-comment">// INCORRECT: modifies the copy, not the original</span>
}

c := Counter{value: <span class="hljs-number">5</span>}
c.Inc()
fmt.Println(c.value) <span class="hljs-comment">// still 5</span>
</code></pre>
<p>With a pointer receiver, it works correctly:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c *Counter)</span> <span class="hljs-title">Inc</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// note the shorthand syntax to (*c).value</span>
    c.value++ <span class="hljs-comment">// CORRECT: modifies the original via the pointer</span>
}

c := Counter{value: <span class="hljs-number">5</span>}
c.Inc()
fmt.Println(c.value) <span class="hljs-comment">// now 6</span>
</code></pre>
<p>Even though the method receives a copy of the pointer, both the copy and the original pointer point to the same struct in memory (in the heap), so changes inside the method affect the original.</p>
<h3 id="heading-idiomatic-go">Idiomatic Go</h3>
<ul>
<li><p>Small structs can use value receivers if mutation isn't needed.</p>
</li>
<li><p>Large structs or any struct that must be mutated should use pointer receivers.</p>
</li>
<li><p>If some methods need pointer receivers, it's common to make all methods use pointer receivers for consistency.</p>
</li>
</ul>
<p>Pointer receivers are arguably the most common and practical use of pointers in Go. They allow methods to mutate state safely without unnecessary copies.</p>
<h2 id="heading-exercises-for-the-reader">Exercises for the Reader</h2>
<p>To solidify your understanding of pointers, try the following exercises:</p>
<ol>
<li><p>Write a function that swaps two integers using pointers.</p>
</li>
<li><p>Create a struct representing a <code>Rectangle</code> with width and height. Write methods to calculate the area and to scale the rectangle by a factor, using pointer receivers.</p>
</li>
</ol>
<h2 id="heading-bonus-weak-pointers-go-124">Bonus: Weak Pointers (Go 1.24+)</h2>
<p>Go 1.24 introduced weak references, which let you hold a reference to a value without preventing it from being garbage-collected. This is useful when you want a cache or auxiliary data structure without prolonging the lifetime of the objects.</p>
<h3 id="heading-what-are-weak-pointers">What Are Weak Pointers?</h3>
<p>A weak pointer is a pointer that does not count toward keeping the referenced object alive. If the only references to an object are weak, the garbage collector can still free it.</p>
<p>Weak pointers are provided by the runtime/weak package:</p>
<pre><code class="lang-go"><span class="hljs-keyword">import</span> <span class="hljs-string">"runtime/weak"</span>

<span class="hljs-keyword">type</span> Cache <span class="hljs-keyword">struct</span> {
    data weak.Map[<span class="hljs-keyword">string</span>, *User]
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    c := Cache{data: weak.MakeMap[<span class="hljs-keyword">string</span>, *User]()}
    u := &amp;User{<span class="hljs-string">"Alice"</span>, <span class="hljs-number">30</span>}

    c.data.Set(<span class="hljs-string">"alice"</span>, u) <span class="hljs-comment">// weak reference stored</span>
}

<span class="hljs-comment">// ...later</span>
<span class="hljs-keyword">if</span> user, ok := c.data.Get(<span class="hljs-string">"alice"</span>); ok {
    fmt.Println(user.Name) <span class="hljs-comment">// Alice</span>
} <span class="hljs-keyword">else</span> {
    fmt.Println(<span class="hljs-string">"User has been garbage collected"</span>)
}
</code></pre>
<p>If <code>u</code> is no longer referenced elsewhere, the garbage collector can reclaim it, even though it exists in the <code>weak.Map</code>.</p>
<p>Essentially, a weak pointer can turn into a nil pointer if the object it points to has been garbage collected. You should always check if it's nil before dereferencing it.</p>
<h3 id="heading-when-to-use-weak-pointers">When to Use Weak Pointers</h3>
<ul>
<li><p>Caches: Keep objects around if they're still in use, but don't prevent GC if not.</p>
</li>
<li><p>Avoid memory leaks: Especially in long-running services where temporary objects could otherwise accumulate.</p>
</li>
<li><p>Auxiliary indexing: Like mapping IDs to objects without controlling their lifetimes.</p>
</li>
</ul>
<p>Weak pointers are an advanced feature and should be used judiciously. Most Go programs will never need them, but in certain scenarios, they can be very useful.</p>
<h2 id="heading-summary-amp-best-practices">Summary &amp; Best Practices</h2>
<ul>
<li><p>Pointers store addresses of variables and allow you to share and mutate data efficiently.</p>
</li>
<li><p>Use <code>&amp;</code> to get an address, <code>*</code> to dereference and declare.</p>
</li>
<li><p>Pointer receivers let methods mutate structs without unnecessary copies.</p>
</li>
<li><p>Be cautious with nil pointers to avoid panics.</p>
</li>
<li><p>Reference types (slices, maps, channels) already share underlying data.</p>
</li>
<li><p>Weak pointers (Go 1.24+) provide advanced memory management for caches or auxiliary structures.</p>
</li>
</ul>
<p>While not as powerful as in languages like C/C++, Go pointers are safe and easy to use. Experiment with them in small programs, and you'll quickly see how they can help you write more efficient and easy-to-read Go code.</p>
<h2 id="heading-solutions-to-exercises">Solutions to Exercises</h2>
<ol>
<li>Swapping two integers using pointers:</li>
</ol>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">swap</span><span class="hljs-params">(a, b *<span class="hljs-keyword">int</span>)</span></span> {
    *a, *b = *b, *a
}

x, y := <span class="hljs-number">1</span>, <span class="hljs-number">2</span>
swap(&amp;x, &amp;y)
fmt.Println(x, y) <span class="hljs-comment">// 2 1</span>
</code></pre>
<p>Here, <code>swap</code> takes two pointers to integers and swaps their values by dereferencing them. Without pointers, you would only swap copies of the integers, leaving the originals unchanged.</p>
<ol start="2">
<li>Rectangle struct with methods:</li>
</ol>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Rectangle <span class="hljs-keyword">struct</span> {
    Width, Height <span class="hljs-keyword">float64</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r *Rectangle)</span> <span class="hljs-title">Area</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> r.Width * r.Height
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r *Rectangle)</span> <span class="hljs-title">Scale</span><span class="hljs-params">(factor <span class="hljs-keyword">float64</span>)</span></span> {
    r.Width *= factor
    r.Height *= factor
}

rect := Rectangle{Width: <span class="hljs-number">3</span>, Height: <span class="hljs-number">4</span>}
fmt.Println(rect.Area()) <span class="hljs-comment">// 12</span>
rect.Scale(<span class="hljs-number">2</span>)
fmt.Println(rect.Area()) <span class="hljs-comment">// 48</span>
</code></pre>
<p>Because <code>Scale</code> modifies the rectangle, it uses a pointer receiver. The <code>Area</code> method could use either a value or pointer receiver since it doesn't modify the struct, but using a pointer receiver is consistent and avoids copying the struct.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
