<?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" version="2.0"><channel><title><![CDATA[Tech Blog]]></title><description><![CDATA[Tech Blog]]></description><link>https://blog.rohitlokhande.in</link><generator>RSS for Node</generator><lastBuildDate>Fri, 10 Apr 2026 03:06:24 GMT</lastBuildDate><atom:link href="https://blog.rohitlokhande.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Listen, React, Repeat: Practical select Techniques in Go]]></title><description><![CDATA[Concurrency is one of Go’s greatest strengths, and channels are the backbone of safe communication between goroutines. But what happens when a goroutine needs to listen to multiple channels simultaneo]]></description><link>https://blog.rohitlokhande.in/listen-react-repeat-practical-select-techniques-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/listen-react-repeat-practical-select-techniques-in-go</guid><category><![CDATA[golang]]></category><category><![CDATA[goroutines]]></category><category><![CDATA[channels in go]]></category><category><![CDATA[select in go]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Wed, 04 Mar 2026 18:11:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/67fd422c4ed60bd8f1867449/c75d4c8e-5f2f-40c3-a88f-c2307c6af6e5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Concurrency is one of Go’s greatest strengths, and channels are the backbone of safe communication between goroutines. But what happens when a goroutine needs to listen to multiple channels simultaneously?</p>
<p>That’s where select comes in. In this article, we’ll break down select in Go from scratch—with simple explanations, real-world analogies, and practical examples you’ll actually remember.</p>
<h2>Why Do We Need select?</h2>
<p>Let’s start with a basic problem</p>
<p>In Go, receiving from a channel looks like this</p>
<pre><code class="language-go">msg := &lt;- ch
</code></pre>
<p>This works fine when</p>
<ul>
<li><p>You’re listening to one channel</p>
</li>
<li><p>You’re okay with blocking</p>
</li>
</ul>
<p>But what if you want</p>
<ul>
<li><p>Listen to multiple channels.</p>
</li>
<li><p>Handle timeouts</p>
</li>
<li><p>Support cancellation</p>
</li>
<li><p>Avoid blocking forever</p>
</li>
</ul>
<p>select solve all this problems.</p>
<h2>What is select in Go?</h2>
<blockquote>
<p>select lets a goroutine wait on multiple channel operations and execute the one that becomes ready first.</p>
</blockquote>
<p>Think of it as:</p>
<ul>
<li><p>switch → works on values</p>
</li>
<li><p>select → works on channels</p>
</li>
</ul>
<h3>Basic Syntax of select</h3>
<pre><code class="language-go">select {
case v := &lt;- ch1:
    // receive from ch1
case v := &lt;- ch2:
    // receive from ch2 
}
</code></pre>
<blockquote>
<p>Important rules:</p>
<ul>
<li><p>select blocks until at least one case is ready</p>
</li>
<li><p>Only one case runs</p>
</li>
<li><p>If multiple cases are ready. Go picks one randomly</p>
</li>
</ul>
</blockquote>
<h2>Real-World Analogy: Restaurant Kitchen</h2>
<p>Imagine a chef in a restaurant kitchen</p>
<ul>
<li><p>New customer orders may arrive.</p>
</li>
<li><p>Ingredient deliveries may arrive.</p>
</li>
<li><p>The restaurant may close.</p>
</li>
</ul>
<p>The chef reacts to whatever happens first.</p>
<p>That’s exactly how select works.</p>
<pre><code class="language-go">select {
case order := &lt;-orders:
    cook(order)
case delivery := &lt;- deliveries;
    store(delivery)
case &lt;- closeShop:
    return
}
</code></pre>
<h2>Example: Waiting on Multiple Channels</h2>
<pre><code class="language-go">package main
import (
    "fmt"
    "time"
)
func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    go func() {
        time.Sleep(1 * time.Second)
        ch1 &lt;- "message from ch1"
    }()
    
    go func(){
        time.Sleep(2 * time.Second)
        ch2 &lt;- "message from ch2"
    }()

    select {
    case msg := &lt;-ch1
        fmt.Println(msg)
    case msg : &lt;-ch2
        fmt.Println(msg)
    }
}
</code></pre>
<p><strong>What happens?</strong></p>
<ul>
<li><p>ch1 sends first</p>
</li>
<li><p>select receives from ch1</p>
</li>
<li><p>Program exits</p>
</li>
</ul>
<h2>What If Multiple Cases Are Ready?</h2>
<p>If more than one channel is ready:</p>
<pre><code class="language-go">select {
    case &lt;-ch1:
        fmt.Println("ch1")
    case &lt;-ch2:
        fmt.Println("ch2")
}
</code></pre>
<p>In this case Go randomly chooses one. It will never rely on order inside select</p>
<h2>Non-Blocking select with default</h2>
<p>Sometimes you don’t want to block.</p>
<pre><code class="language-go">select {
case msg := &lt;-ch:
    fmt.Println(msg)
default:
    fmt.Println("No message available")
}
</code></pre>
<p>Why this matters:</p>
<ul>
<li><p>Prevents deadlocks</p>
</li>
<li><p>Useful for polling</p>
</li>
<li><p>Makes select non-blocking</p>
</li>
</ul>
<h2>Common Beginner Mistake</h2>
<p>This can deadlock</p>
<pre><code class="language-go">select {
case msg := &lt;-ch:
    fmt.Println(msg)
}
</code></pre>
<p>If <code>ch</code> never sends, the program blocks forever.</p>
<p>Always consider:</p>
<ul>
<li><p>done channel</p>
</li>
<li><p>timeout</p>
</li>
<li><p>default</p>
</li>
</ul>
<h3><strong>Done Channel (Cancellation Pattern)</strong></h3>
<p>This allows external control to stop waiting</p>
<pre><code class="language-go">package main

import (
	"fmt"
	"time"
)

func main() {
	ch := make(chan string)
	done := make(chan struct{})

	go func() {
		time.Sleep(2 * time.Second)
		close(done) // signal cancellation
	}()

	select {
	case msg := &lt;-ch:
		fmt.Println("Received:", msg)

	case &lt;-done:
		fmt.Println("Operation cancelled")
	}
}
</code></pre>
<p><strong>What happens?</strong></p>
<ul>
<li><p><code>ch</code> never sends</p>
</li>
<li><p>After 2 seconds, <code>done</code> closes</p>
</li>
<li><p><code>select</code> exists safely</p>
</li>
</ul>
<h3>Use Timeout (time.After)</h3>
<p>very common in production systems.</p>
<pre><code class="language-go">package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)
    
    select {
    case msg := &lt;-ch:
        fmt.Println("Received:",msg)
    case &lt;-time.After(3 * time.Second)
        fmt.Println("Timeout occurred")
    }

}
</code></pre>
<p><strong>What happens?</strong></p>
<ul>
<li><p><code>ch</code> never sends</p>
</li>
<li><p>After 3 seconds -&gt; timeout case executes</p>
</li>
<li><p>Program continues safely</p>
</li>
</ul>
<p>This prevents waiting forever.</p>
<h3>Use default (Non-Blocking Select)</h3>
<p>This makes select run immediately if no case is ready.</p>
<pre><code class="language-go">package main

import "fmt"

func main() {
    ch := make(chan string)
    select {
    case msg := &lt;- ch:
        fmt.Println("Received:", msg)
    default:
        fmt.Println("No message available")
    }
}
</code></pre>
<p><strong>What happens?</strong></p>
<ul>
<li><p>ch has no data</p>
</li>
<li><p>default runs immediately</p>
</li>
<li><p>Program does NOT block</p>
</li>
</ul>
<h2>How select Is Evaluated in Go</h2>
<p>Many developers use select in Go, but very few truly understand how it is evaluated internally.</p>
<p>This is an important concept especially for interviews and writing correct concurrent code.</p>
<p>Let's break it down clearly.</p>
<p>When Go executes a select statement, it does NOT check cases one-by-one from top to bottom. Instead, it follows this process:</p>
<h3>Step-by-Step Evaluation</h3>
<p><strong>Step 1: Evaluate All Case Expressions</strong></p>
<p>Before choosing any case, Go:</p>
<ul>
<li><p>Evaluates all channel expressions</p>
</li>
<li><p>Evaluates all values being sent</p>
</li>
<li><p>Executes any function calls inside the cases.</p>
</li>
</ul>
<p>This happens before Go decides which case to run.</p>
<p><strong>Example: Function Calls Run First</strong></p>
<pre><code class="language-go">package main

import "fmt"

func getValue(name string) string {
    fmt.Println("Evaluating: ",name)
    return name
}

func main() {
    ch1 := make(chan string, 1)
    ch2 := make(chan string, 1)

    select {
    case ch1 &lt;- getValue("A"):
    fmt.Println("ch1 case is selected")
    case ch2 &lt;- getValue("B"): 
    fmt.Println("ch1 case is selected")
    }
    
    fmt.Println("Done")

}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Evaluating:  A
Evaluating:  B
ch1 case is selected
Done
</code></pre>
<p>Even through only once case is selected, and both functions executed. You can see that is output.</p>
<p>This proves evaluation happens before selection.</p>
<p><strong>Step 2: Check Which Cases Are Ready</strong></p>
<p>After evaluation:</p>
<ul>
<li><p>Receive case is ready if channel has data.</p>
</li>
<li><p>Send case is ready if receiver exists (or buffer has space).</p>
</li>
<li><p>Closed channel receive is always ready.</p>
</li>
<li><p>Nil channel is never ready.</p>
</li>
</ul>
<p><strong>Receive Case Ready (Channel Has Data)</strong></p>
<pre><code class="language-go">package main
import "fmt"

func main() {
    ch := make(chan string,1)
    ch &lt;- "Hello"
    
    select {
    case msg := &lt;-ch:
        fmt.Println("Received:",msg)    
    }
}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Received: Hello
</code></pre>
<p>Channel has data -&gt; receive case is ready.</p>
<p><strong>Send Case Ready (Buffered Channel Has Space)</strong></p>
<pre><code class="language-go">package main

import "fmt"

func main(){
    ch := make(chan string,1)
    select {
    case ch &lt;- "Hi":
        fmt.Println("Send successfully")
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Sent successfully
</code></pre>
<p><strong>Closed Channel Receive Is Always Ready</strong></p>
<pre><code class="language-go">package main

import "fmt"

func main() {
	ch := make(chan string)
	close(ch)

	select {
	case msg := &lt;-ch:
		fmt.Println("Received from closed channel:", msg)
	}
}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Received from closed channel:
</code></pre>
<p>Closed channel immediately returns zero value.</p>
<p><strong>Nil Channel Is Never Ready</strong></p>
<pre><code class="language-go">package main

import "fmt"

func main() {
	var ch chan string // nil channel

	select {
	case msg := &lt;-ch:
		fmt.Println(msg)

	default:
		fmt.Println("Nil channel blocks forever")
	}
}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Nil channel blocks forever
</code></pre>
<p><strong>Step 3: Chose a case</strong></p>
<ul>
<li><p>If one case is ready -&gt; execute it.</p>
</li>
<li><p>If multiple are ready -&gt; pick once randomly</p>
</li>
<li><p>If none are ready:</p>
<ul>
<li><p>If default exists -&gt; run default</p>
</li>
<li><p>Otherwise -&gt; block until one becomes ready.</p>
</li>
</ul>
</li>
</ul>
<h2>When Should you Use select?</h2>
<ul>
<li><p>Listening to multiple channels</p>
</li>
<li><p>Implementing timeouts</p>
</li>
<li><p>Handling cancellation</p>
</li>
<li><p>Writing long-running goroutines</p>
</li>
</ul>
<h2>Interview FAQs</h2>
<ol>
<li><p><strong>Does select check cases in order?</strong></p>
<p>-&gt; No - selection random if multiple are ready.</p>
</li>
<li><p><strong>Can select block forever?</strong></p>
<p>-&gt; Yes, if no case is ready and no default.</p>
</li>
<li><p><strong>Can select send and receive?</strong></p>
<p>-&gt; Yes - both are supported.</p>
</li>
<li><p><strong>What happens if no case in select is ready?</strong></p>
<p>-&gt; If there is no default case, select blocks forever until one case becomes ready.<br />If there is a default case, it executes immediately (non-blocking behaviour).</p>
</li>
<li><p><strong>What happens if multiple cases are ready?</strong></p>
<p>-&gt; Go chooses one randomly.<br />It does not:<br />- Check in order<br />- Prioritise top case<br />- Execute multiple cases</p>
</li>
<li><p><strong>Does select execute all ready cases?</strong></p>
<p>-&gt; No. It executes only one case per select execution<br />To process continuously, you must use it inside a loop:</p>
<pre><code class="language-go">for {
  select {
  case msg := &lt;- ch:
        fmt.Println(msg)
 
  }
 
}


</code></pre>
</li>
<li><p><strong>How would you design a worker pool using select?</strong></p>
<p>-&gt;<br />- job channel<br />- result channel<br />- done channel<br />- timeout<br />- context cancellation</p>
</li>
</ol>
<h2>Conclusion</h2>
<p><code>select</code> is the idiomatic tool in Go for waiting on multiple channel operations: it enables listening to several channels at once, implementing timeouts, and responding to cancellation in a clear, concurrent-safe way. Remember the core rules—<code>select</code> blocks until a case is ready, only one case runs, and if multiple are ready Go picks one at random—and use those guarantees to design predictable, non-blocking goroutines.</p>
<p>Practical tips</p>
<ul>
<li><p>Use a <code>for { select { ... } }</code> loop to keep a goroutine responsive to new events.</p>
</li>
<li><p>Use <code>default</code> sparingly to avoid unintended busy-waiting; use it when you explicitly want non-blocking behavior.</p>
</li>
<li><p>Prefer <code>context.Context</code> (or <code>time.Timer</code>/<code>time.After</code>) for cancellation and timeouts instead of ad-hoc channel hacks.</p>
</li>
<li><p>Be careful with nil channels and closed channels—both affect readiness and can cause selects to behave unexpectedly.</p>
</li>
<li><p>Ensure selects can exit to avoid leaking goroutines (handle shutdown cases explicitly).</p>
</li>
<li><p>Test concurrency with the race detector (<code>go test -race</code>) and static tools (<code>go vet</code>, linters).</p>
</li>
</ul>
<p>Mastering <code>select</code> will make your concurrent Go code more robust and easier to reason about. Practice with small examples and read the official docs and examples to reinforce these patterns.</p>
]]></content:encoded></item><item><title><![CDATA[How Do Go Channels Work? An Easy Explanation]]></title><description><![CDATA[When you start learning Go, you quickly hear two thingsgoroutines → run functions concurrentlychannels → help goroutine talk to each other
But why do they exist?
Because when multiple goroutines run at the same time, you need a safe way to share data...]]></description><link>https://blog.rohitlokhande.in/how-do-go-channels-work-an-easy-explanation</link><guid isPermaLink="true">https://blog.rohitlokhande.in/how-do-go-channels-work-an-easy-explanation</guid><category><![CDATA[golang]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[goroutines]]></category><category><![CDATA[channels in go]]></category><category><![CDATA[concurrency-in-go]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Sat, 13 Dec 2025 05:51:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765337010161/2596b31f-fabd-49cd-aab0-703710c28d40.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you start learning Go, you quickly hear two things<br />goroutines → run functions concurrently<br />channels → help goroutine talk to each other</p>
<p>But why do they exist?</p>
<p>Because when multiple goroutines run at the same time, you need a safe way to share data between them without using locks, mutexes, or shared memory headaches.</p>
<p>So Go follows:</p>
<blockquote>
<p>“Do not communicate by sharing memory; share memory by communicating.”</p>
</blockquote>
<p>This is exactly what channels provides.</p>
<h2 id="heading-what-is-a-channel">What Is a Channel?</h2>
<p>A channel is a pipe that lets one goroutine send data to another goroutine.</p>
<pre><code class="lang-go">Goroutine A  ---- data ----&gt;  Goroutine B
              (via channel)
</code></pre>
<p>You can think of it like a water pipe for values.</p>
<h2 id="heading-creating-a-channel">Creating a Channel</h2>
<pre><code class="lang-go">ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
</code></pre>
<p>This creates a channel that can send / receive integers.</p>
<h2 id="heading-sending-amp-receiving">Sending &amp; Receiving</h2>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)

    <span class="hljs-comment">// Sender goroutine</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        ch &lt;- <span class="hljs-number">10</span> <span class="hljs-comment">// sending data</span>
    }()

    v := &lt;-ch <span class="hljs-comment">//receiving data</span>
    fmt.Println(v)
}
</code></pre>
<p>What happens?</p>
<ul>
<li><p>The goroutine sends 10 into the channel.</p>
</li>
<li><p>The main goroutine waits until it receives that value.</p>
</li>
<li><p>Output :10</p>
</li>
</ul>
<p>Channels block by default → meaning the sender waits until someone receives the data.</p>
<p>This prevents many concurrency bugs automatically.</p>
<h2 id="heading-why-blocking-is-actually-useful">Why Blocking Is Actually Useful</h2>
<p>Blocking ensures synchronisation without locks.</p>
<pre><code class="lang-go">done: <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>)

<span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Task running..."</span>)
    done &lt;- <span class="hljs-literal">true</span> <span class="hljs-comment">// signals completion</span>
}()
&lt;- done <span class="hljs-comment">// waits for task</span>
fmt.Println(<span class="hljs-string">"Task finished!"</span>)
</code></pre>
<p>No mutex. No busy waiting. The channel does all the synchronisation.</p>
<h2 id="heading-buffered-vs-unbuffered-channels">Buffered vs Unbuffered Channels</h2>
<p>By default, channels are unbuffered i.e send blocks until receive happens.</p>
<p>Let’s under this with Restaurant Analogy.</p>
<h3 id="heading-unbuffered-channel-chef-hands-plate-directly-to-waiter">Unbuffered Channel = Chef hands plate directly to waiter</h3>
<p>Senario</p>
<p>The kitchen has no counter, no shelf, no tray to place food on.</p>
<p>Only option → Chef must hand the plate directly to a waiter</p>
<p><strong>What happens?</strong></p>
<ul>
<li><p>Chef prepares the dish.</p>
</li>
<li><p>Chef extends the plate to give it to a waiter.</p>
</li>
<li><p>If no waiter is available, the chef cannot let go of the plate.</p>
</li>
<li><p>So the chef stands and waits until a waiter arrives and takes it.</p>
</li>
<li><p>Once the waiter grabs the plate, both continue.</p>
</li>
</ul>
<p><strong>Meaning in GO</strong></p>
<ul>
<li><p>Sender waits until the receiver is ready.</p>
</li>
<li><p>Receiver waits until the sender sends.</p>
</li>
<li><p>Communication is synchronous.</p>
</li>
</ul>
<pre><code class="lang-go">ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>) <span class="hljs-comment">// unbuffered</span>

<span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
    ch &lt;- <span class="hljs-string">"Pasta"</span>
    <span class="hljs-comment">// waits until someone receives</span>
}()

fmt.Println(&lt;-ch) <span class="hljs-comment">// receives and unblocks chef</span>
</code></pre>
<p>“Serving must happen instantly — no place to put the dish.“</p>
<h3 id="heading-buffered-channel-chef-places-plates-on-a-counter-tray-shelf">Buffered Channel = Chef places plates on a counter (tray / shelf)</h3>
<p>senario</p>
<p>Now the kitchen has a food counter with space for 3 plates.</p>
<ul>
<li><p>Chef puts dishes on the counter.</p>
</li>
<li><p>Waiters pick them up later.</p>
</li>
</ul>
<p><strong>What happens?</strong></p>
<ul>
<li><p>Chef finishes dish and places it on counter.</p>
</li>
<li><p>No need to wait for a waiter.</p>
</li>
<li><p>Chef continues cooking.</p>
</li>
<li><p>Waiter picks plates when free.</p>
</li>
<li><p>If the counter becomes full chef must stop and wait.</p>
</li>
</ul>
<p><strong>Meaning in go</strong></p>
<ul>
<li><p>Sender places data in buffer does not wait.</p>
</li>
<li><p>Receiver picks up whenever ready.</p>
</li>
<li><p>Only blocks when buffer is full.</p>
</li>
</ul>
<p><strong>Buffered Channel</strong></p>
<pre><code class="lang-go">ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)
</code></pre>
<p>This channel can hold 2 values without blocking.</p>
<pre><code class="lang-go">ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)

ch &lt;- <span class="hljs-number">1</span>
ch &lt;- <span class="hljs-number">2</span> <span class="hljs-comment">// ok</span>

<span class="hljs-comment">// ch &lt;- 3 // would block because buffer is full</span>

fmt.Println(&lt;- ch) <span class="hljs-comment">// 1</span>
fmt.Println(&lt;- ch) <span class="hljs-comment">// 2</span>
</code></pre>
<p>Use buffered channels when you want to control throughput.</p>
<h3 id="heading-final-understanding">Final Understanding</h3>
<p><strong>Unbuffered</strong></p>
<blockquote>
<p>“Chef waits until a waiter is RIGHT THERE to take the dish.“</p>
</blockquote>
<p><strong>Buffered</strong></p>
<blockquote>
<p>“Chef places dish on counter and keeps cooking - unless counter fills up.“</p>
</blockquote>
<h2 id="heading-directional-channels">Directional Channels</h2>
<p>In Go, channels can be restricted so a function can only send or only receive.<br />This improves safety by preventing incorrect usage.</p>
<p><strong>Why Use Directional Channels?</strong></p>
<ul>
<li><p>Prevent accidental receiving when a goroutine should only send.</p>
</li>
<li><p>Improve readability like “this function only sends data”.</p>
</li>
<li><p>Allow the compiler to catch misuses early.</p>
</li>
</ul>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>, jobs &lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, results <span class="hljs-keyword">chan</span> &lt;- <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> j := <span class="hljs-keyword">range</span> jobs {
        results &lt;- j * <span class="hljs-number">2</span>
    }
}
</code></pre>
<ul>
<li><p><code>jobs &lt;-chan int</code> → receive only</p>
</li>
<li><p><code>results chan &lt;- int</code> → send only</p>
</li>
</ul>
<p>In this implementation worker cannot misuse channels</p>
<ul>
<li><p>If it tries to send on jobs, compiler error.</p>
</li>
<li><p>If it tries to receive from results, compiler error.</p>
</li>
</ul>
<p><strong>Why It Matters?</strong></p>
<p>In large systems:</p>
<ul>
<li><p>Directional channels enforce correctness.</p>
</li>
<li><p>They reduce bugs caused by wrong channel usage.</p>
</li>
</ul>
<h2 id="heading-closing-a-channel">Closing a Channel</h2>
<p>Closing a channel signals:</p>
<blockquote>
<p>“No more values will be sent“</p>
</blockquote>
<p>Workers can safely stop processing when the channel is closed.</p>
<p>Example — Using close()</p>
<pre><code class="lang-go"><span class="hljs-built_in">close</span>(jobs)
</code></pre>
<p>Now workers reading from jobs will keep receiving until all values are consumed, then exit gracefully.</p>
<p><strong>How receivers detect closure</strong></p>
<pre><code class="lang-go">v, ok := &lt;-jobs
<span class="hljs-keyword">if</span> !ok {
    fmt.Println(<span class="hljs-string">"channel closed"</span>)
}
</code></pre>
<p><strong>Key Rules:</strong></p>
<ul>
<li><p>Only the sender should close the channel.</p>
</li>
<li><p>Closing a channel twice → panic.</p>
</li>
<li><p>Receiving from closed channel → zero-value but safe.</p>
</li>
</ul>
<h2 id="heading-deadlocks">Deadlocks</h2>
<p>A deadlock happens when goroutine are stuck waiting on each other forever.</p>
<p>Go detect this and panics.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
    ch &lt;- <span class="hljs-number">1</span> <span class="hljs-comment">// no receiver -&gt; deadlock</span>
}
</code></pre>
<p>In this above code the main goroutine is waiting to send, but no goroutine is receiving.</p>
<p><strong>Deadlock in Receivers</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
    fmt.Println(&lt;-ch) <span class="hljs-comment">// no sender</span>
}
</code></pre>
<h2 id="heading-goroutine-leaks">Goroutine Leaks</h2>
<p>A goroutine leak occurs when a goroutine is started but then enters a permanent waiting state, unable to complete its execution, and there is no mechanism to stop it. It remains alive until the entire program terminates.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(ch &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> v := <span class="hljs-keyword">range</span> ch { <span class="hljs-comment">// here waits forever if channel never closed</span>
        fmt.Println(v)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
    <span class="hljs-keyword">go</span> worker(ch)
    <span class="hljs-comment">// forgot to close or send</span>
}
</code></pre>
<p>In this example, after calling the worker in another goroutine, we are not sending any values to that channel. To fix these leaks, always close channels when no more values will be sent.</p>
<h3 id="heading-resources-consumed-by-a-leaked-goroutine">Resources Consumed by a Leaked Goroutine</h3>
<p>A leaked goroutine is not free. It continuously holds onto system resources, which can lead to prerfromance degradation. Below are resources consumed by the leaked goroutine.</p>
<ol>
<li><p><strong>Memory (Stack)</strong></p>
<p> Every goroutine starts with a small amount of memory for its stack typically 2 KB while small, this memory is continuously allocated and reserved.</p>
<ul>
<li>If you have a bug that causes a goroutine leak every time an event occurs, and that event happens frequently, the number of leaks goroutines will climb, and the total memory consumed by their stacks will grow linearly. For example 100,000 leaked goroutines will consume about 200 MB of stack memory alone.</li>
</ul>
</li>
<li><p><strong>CPU and Scheduling Overheads</strong></p>
<p> Even through a leaked goroutine and isn’t actively running code, it still costs the Go runtime (the scheduler) resources</p>
<ul>
<li><p>Scheduler Management : The Go scheduler must maintain the data structure for every active goroutine. The scheduler periodically checks the status of these blocked goroutines to see if they can be unblocked.</p>
</li>
<li><p>Context Switching: While minimal, if the goroutine briefly wakes up due to a false signal or is examined by the scheduler, it can contribute to small, unnecessary context-switching overhead.</p>
</li>
</ul>
</li>
<li><p><strong>Channel Management</strong></p>
<p> The channel <code>ch</code> itself is also part of the resource consumption. The channel’s internal data structure must track that one goroutine is currently blocked waiting to receive from it.</p>
</li>
</ol>
<p>To prevent the leak, must either:</p>
<ol>
<li><p>Close the channel after sending all necessary data</p>
</li>
<li><p>Use a different synchronization primitive like a <code>sync.WaitGroup</code> if the worker should exit after completing a specific job instead of waiting for the channel to close.</p>
</li>
</ol>
<h2 id="heading-how-waitgroup-prevents-premature-exit-leaks">How <code>WaitGroup</code> Prevents Premature Exit Leaks</h2>
<p><code>sync.WaitGroup</code> doesn’t directly stop a goroutine from getting stuck, it provides the mechanism to ensure the entire application waits for the worker to complete its execution path, which is key to avoid a leak if the program were to continue running.</p>
<p>In a simple scenario without a <code>WaitGroup</code>, if the <code>main</code> function finishes, the program terminates immediately, potentially killing active workers mid-execution, or, as in previous examples causing a deadlock.</p>
<ol>
<li><p><strong>Waiting for Known Finite Tasks</strong></p>
<p> If you know a goroutine’s job is finite, the <code>WaitGroup</code> guarantees the program won’t exit until that job is done.</p>
<p> <strong>Example: Clean Exit without a Leak</strong></p>
<p> In this pattern, the <code>worker</code> has a clear, finite task. The <code>WaitGroup</code> ensures its completion.</p>
<pre><code class="lang-go"> <span class="hljs-keyword">package</span> main

 <span class="hljs-keyword">import</span> (
     <span class="hljs-string">"fmt"</span>
     <span class="hljs-string">"sync"</span>
     <span class="hljs-string">"time"</span>
 )

 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>, wg *sync.WaitGroup)</span></span> {
     <span class="hljs-comment">// The DEFER ensures wg.Done() is called no matter what.</span>
     <span class="hljs-keyword">defer</span> wg.Done() 

     fmt.Printf(<span class="hljs-string">"Worker %d starting...\n"</span>, id)
     time.Sleep(time.Millisecond * <span class="hljs-number">100</span>) <span class="hljs-comment">// Finite task</span>
 }

 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
     <span class="hljs-keyword">var</span> wg sync.WaitGroup
     wg.Add(<span class="hljs-number">1</span>) 

     <span class="hljs-keyword">go</span> worker(<span class="hljs-number">1</span>, &amp;wg) 

     <span class="hljs-comment">// Main blocks here, guaranteeing the worker finishes its task.</span>
     wg.Wait() 
     fmt.Println(<span class="hljs-string">"Program complete."</span>)
 }
 <span class="hljs-comment">// Outcome: The worker runs to completion, the counter reaches zero, </span>
 <span class="hljs-comment">// and the program exits cleanly. No leak.</span>
</code></pre>
</li>
<li><p>Preventing Leaks from Unclosed Channels Using <code>WaitGroup</code> with <code>close</code></p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(ch &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)</span></span> {
     <span class="hljs-keyword">for</span> v := <span class="hljs-keyword">range</span> ch { <span class="hljs-comment">// here waits forever if channel never closed</span>
         fmt.Println(v)
     }
 }

 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
     ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
     <span class="hljs-keyword">go</span> worker(ch)
     <span class="hljs-comment">// forgot to close or send</span>
 }
</code></pre>
<p> In above leaky example involved a worker blocked on an unclosed channel. <code>WaitGroup</code> can’t fix that specific blocking mechanism, but it can work in conjunction with channel closing to provide robust leak-free concurrency.</p>
<p> <strong>Example: Leak-Free Channel Consumption</strong></p>
<p> In this the <code>WaitGroup</code> ensures the <code>main</code> function waits long enough for the sender to complete and close the channel, which, in turn, allows the receiver (<code>worker</code>) to exit cleanly.</p>
<pre><code class="lang-go"> <span class="hljs-keyword">package</span> main

 <span class="hljs-keyword">import</span> (
     <span class="hljs-string">"fmt"</span>
     <span class="hljs-string">"sync"</span>
 )

 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sender</span><span class="hljs-params">(ch <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">int</span>, wg *sync.WaitGroup)</span></span> {
     <span class="hljs-keyword">defer</span> wg.Done() <span class="hljs-comment">// Signal completion of sending</span>

     <span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">3</span>; i++ {
         ch &lt;- i <span class="hljs-comment">// Send data</span>
     }
     <span class="hljs-comment">// Critical: Close the channel to signal EOD (End of Data)</span>
     <span class="hljs-built_in">close</span>(ch) 
     fmt.Println(<span class="hljs-string">"Sender finished and closed channel."</span>)
 }

 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">receiver</span><span class="hljs-params">(ch &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, wg *sync.WaitGroup)</span></span> {
     <span class="hljs-keyword">defer</span> wg.Done() <span class="hljs-comment">// Signal completion of receiving</span>

     <span class="hljs-comment">// This loop will exit gracefully when 'ch' is closed</span>
     <span class="hljs-keyword">for</span> v := <span class="hljs-keyword">range</span> ch { 
         fmt.Println(<span class="hljs-string">"Received:"</span>, v)
     }
     fmt.Println(<span class="hljs-string">"Receiver finished."</span>)
 }

 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
     <span class="hljs-keyword">var</span> wg sync.WaitGroup
     ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)

     <span class="hljs-comment">// Add for BOTH sender and receiver</span>
     wg.Add(<span class="hljs-number">2</span>) 

     <span class="hljs-keyword">go</span> sender(ch, &amp;wg)
     <span class="hljs-keyword">go</span> receiver(ch, &amp;wg)

     fmt.Println(<span class="hljs-string">"Waiting for all tasks to complete..."</span>)
     wg.Wait() <span class="hljs-comment">// Main waits for both goroutines to call Done()</span>
     fmt.Println(<span class="hljs-string">"All goroutines completed successfully."</span>)
 }
 <span class="hljs-comment">// Outcome: Both goroutines finish their work and exit gracefully. No leak.</span>
</code></pre>
<p> In this,</p>
<ol>
<li><p><code>sender</code> goroutine sends its data and closes the channel.</p>
</li>
<li><p>the <code>receiver</code> goroutine’s <code>for v := range</code> ch loop detects the close and exits cleanly, calling <code>wg.Done()</code>.</p>
</li>
<li><p>The <code>main</code> goroutine is guaranteed to wait until the <code>receiver</code> exits, preventing the program from termination early and leaving the <code>receiver</code> stuck.</p>
</li>
</ol>
</li>
</ol>
<h2 id="heading-real-world-example-worker-pool-using-channels">Real World Example: Worker Pool Using Channels</h2>
<p>This demonstrates how channels help coordinate many goroutines.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>, jobs &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>,results <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> j := <span class="hljs-keyword">range</span> jobs {
        results &lt;- j * <span class="hljs-number">2</span> <span class="hljs-comment">// processing</span>
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    jobs := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span> ,<span class="hljs-number">5</span>)
    results := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">5</span>)

    <span class="hljs-comment">// 3 worker</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;=<span class="hljs-number">3</span>; i++ {
        <span class="hljs-keyword">go</span> worker(i,jobs, results)
    }

    <span class="hljs-comment">// sending 5 jobs</span>
    <span class="hljs-keyword">for</span> j := <span class="hljs-number">1</span>; j&lt;= <span class="hljs-number">5</span>; j++ {
        jobs &lt;- j
    }
    <span class="hljs-built_in">close</span>(jobs)

    <span class="hljs-comment">// receiving results</span>
    <span class="hljs-keyword">for</span> r := <span class="hljs-number">1</span>; r &lt;= <span class="hljs-number">5</span>; r++ {
        fmt.Println(&lt;- results)
    }
}
</code></pre>
<p><strong>Output</strong></p>
<pre><code class="lang-go"><span class="hljs-number">2</span>
<span class="hljs-number">4</span>
<span class="hljs-number">6</span>
<span class="hljs-number">8</span>
<span class="hljs-number">10</span>
</code></pre>
<h3 id="heading-what-is-above-code">What is Above Code?</h3>
<p>This is a worker pool example a very common concurrency pattern in Go.</p>
<ul>
<li><p>You have multiple worker (goroutines) ready to process jobs.</p>
</li>
<li><p>Jobs are given through a channel.</p>
</li>
<li><p>Workers take a job, process it, and send the result back.</p>
</li>
</ul>
<p>This is used in real systems like</p>
<ul>
<li><p>Background job queues</p>
</li>
<li><p>Web servers</p>
</li>
<li><p>Task processors</p>
</li>
<li><p>Email senders</p>
</li>
<li><p>Image processing pipelines</p>
</li>
</ul>
<p><strong>Setp 1: Worker Function</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>, jobs &lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, results <span class="hljs-keyword">chan</span> &lt;- <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> j := <span class="hljs-keyword">range</span> jobs {
        results &lt;- j * <span class="hljs-number">2</span>
    }
}
</code></pre>
<p>What is happening?</p>
<ol>
<li><p><code>jobs &lt;- chan int</code>  </p>
<p> This worker can only receive jobs.  </p>
</li>
<li><p><code>results chan &lt;- int</code>  </p>
<p> This worker can only send results.  </p>
</li>
<li><p><code>for j := range jobs</code>  </p>
<p> Keeps taking jobs until channel closes.  </p>
</li>
<li><p><code>results &lt;- j * 2</code>  </p>
<p> “Processing“ the job (multiplying by 2)  </p>
</li>
</ol>
<p><strong>Real-World analogy:</strong></p>
<p>Think of these worker as 3 employees sitting in a factory taking tasks (jobs channel) and producing output (results channel)  </p>
<p><strong>Step 2: Creating Job and Result Channels</strong></p>
<pre><code class="lang-go">jobs := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">5</span>)
results := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">5</span>)
</code></pre>
<ul>
<li><p>Jobs channel holds up to 5 tasks.</p>
</li>
<li><p>Results channel holds up to 5 outputs.</p>
</li>
</ul>
<p>This buffer prevents workers from blocking too much.</p>
<p><strong>Step 3: Starting 3 Workers</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">3</span>; i++ {
    <span class="hljs-keyword">go</span> worker(i, jobs, results)
}
</code></pre>
<p>This starts 3 goroutines, each running the worker function.</p>
<p><strong>Step 4: Sending Jobs</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> j: <span class="hljs-number">1</span>: j&lt;=<span class="hljs-number">5</span>; j++ {
    jobs &lt;- j
}
<span class="hljs-built_in">close</span>(jobs)
</code></pre>
<p>You are giving the workers 5 tasks: 1, 2, 3, 4, 5.</p>
<p>Once all jobs are send, you close the channel t signal</p>
<blockquote>
<p>“No more tasks. Finish what you have and exit.“</p>
</blockquote>
<p>Without closing, workers would wait forever and cause a deadlock.  </p>
<p><strong>Step 5: Receiving Results</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> r := <span class="hljs-number">1</span>; r &lt;= <span class="hljs-number">5</span>; r++ {
    fmt.Println(&lt;-results)
}
</code></pre>
<p>You collect 5 results because you send 5 jobs.</p>
<p>Workers may complete jobs in any order, because they run concurrently.</p>
<h3 id="heading-why-is-this-example-important">Why Is This Example Important?</h3>
<p>Because it teaches several core Go concurrency ideas</p>
<ul>
<li><p>Goroutines work independently.</p>
</li>
<li><p>Channels coordinate data flow.</p>
</li>
<li><p>Closing channels signals “no more work“</p>
</li>
<li><p>Multiple goroutines can read from the same channel safely</p>
</li>
<li><p>Worker pools improve performance automatically.</p>
</li>
</ul>
<p>Let’s understand channel more by taking real world use cases.</p>
<h2 id="heading-unbuffered-channel-payment-confirmation-system">Unbuffered Channel - Payment Confirmation System</h2>
<p>Imagine you are making a payment on UPI / Paytm / Google Pay.</p>
<p>You press “Pay“, and your app waits until the bank says : Payment Success</p>
<p>It cannot move ahead until it receives a response.</p>
<p>This is exactly unbuffered behaviour.</p>
<ul>
<li><p>App = Sender</p>
</li>
<li><p>Bank server = Receiver</p>
</li>
<li><p>Confirmation = Data</p>
</li>
<li><p>App must wait → It blocks</p>
</li>
</ul>
<p>This ensures strict, synchronised communication.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">bankServer</span><span class="hljs-params">(confirm <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)</span></span> {
    time.Sleep(<span class="hljs-number">2</span> * time.Second) <span class="hljs-comment">// Simulate processing</span>
    confirm &lt;- <span class="hljs-string">"Payment Successful"</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    confirm := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>) <span class="hljs-comment">// unbuffered</span>
    fmt.Println(<span class="hljs-string">"Initiating Payment..."</span>)
    <span class="hljs-keyword">go</span> bankServer(confirm)
    <span class="hljs-comment">// Waiting for confirmation (blocks)</span>
    status := &lt;- confirm
    fmt.Println(<span class="hljs-string">"Bank Response:"</span>,status)
    fmt.Println(<span class="hljs-string">"Order Placed!"</span>)
}
</code></pre>
<p><strong>Explaination</strong></p>
<ol>
<li><p>User clicks pay → request goes to bank.</p>
</li>
<li><p>confirm := make(chan string) creates an unbuffered channel.</p>
</li>
<li><p>Your app sends the request and waits at:</p>
<pre><code class="lang-go"> status := &lt;-confirm
</code></pre>
</li>
<li><p>Bank server goroutine sleeps for 2 seconds (Payment process simulation)</p>
</li>
<li><p>Bank sends confirmation</p>
<pre><code class="lang-go"> confirm &lt;- <span class="hljs-string">"Payment Successful"</span>
</code></pre>
</li>
<li><p>Your app resumes and continues processing.</p>
</li>
</ol>
<h3 id="heading-why-unbuffered-is-best">Why Unbuffered is Best</h3>
<ul>
<li><p>Payment must not continue without server confirmation.</p>
</li>
<li><p>Forces Synchronous, guaranteed handover.</p>
</li>
<li><p>Prevents inconsistency states like</p>
<ul>
<li><p>Payment done but no order placed</p>
</li>
<li><p>Order placed twice</p>
</li>
<li><p>Payment timeout errors</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-buffered-channel-logging-system">Buffered Channel - Logging System</h2>
<p>Imagine your service receives hundreds of requests per second.</p>
<p>Every request generates logs:</p>
<ul>
<li><p>“User logged in“</p>
</li>
<li><p>“Payment initiated“</p>
</li>
<li><p>“Order created“</p>
</li>
</ul>
<p>If you write logs synchronously (unbuffered)</p>
<ul>
<li><p>Requests must WAIT until the log is written</p>
</li>
<li><p>Reduces performance</p>
</li>
<li><p>Causes slow API Response.</p>
</li>
</ul>
<p>Instead, logs are pushed into a buffer, and a background goroutine writes them to file/database.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">logWriter</span><span class="hljs-params">(logs &lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-keyword">for</span> log := <span class="hljs-keyword">range</span> logs {
        time.Sleep(<span class="hljs-number">500</span> * time.Millisecond)
        fmt.Println(<span class="hljs-string">"Logged:"</span>,log)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    logs := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>, <span class="hljs-number">10</span>) <span class="hljs-comment">// buffered log queue</span>

    <span class="hljs-keyword">go</span> logWriter(logs)

    <span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">5</span>; i++ {
        fmt.Println(<span class="hljs-string">"Received request"</span>,i)
        logs &lt;- fmt.Sprintf(<span class="hljs-string">"Request %d processed"</span>,i)<span class="hljs-comment">// fast enqueue</span>
    }
    <span class="hljs-built_in">close</span>(logs)
    time.Sleep(<span class="hljs-number">3</span> * time.Second)
}
</code></pre>
<h3 id="heading-why-buffered">Why buffered?</h3>
<ul>
<li><p>Logging is slow</p>
</li>
<li><p>Request processing is fast</p>
</li>
<li><p>Buffered channel prevents the fast operation from blocking.</p>
</li>
</ul>
<h2 id="heading-buffered-unbuffered-hybrid-video-streaming-pipeline">Buffered + Unbuffered Hybrid - Video Streaming Pipeline</h2>
<p>In Youtube / Netflix video processing</p>
<ul>
<li><p>State 1: Video Upload</p>
</li>
<li><p>State 2 : Video encoding</p>
</li>
<li><p>State 3 : Thumbnail generation</p>
</li>
</ul>
<p>These require different channel types</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Stage</td><td>Behavior</td><td>Perfect Channel</td></tr>
</thead>
<tbody>
<tr>
<td>Upload → Queue</td><td>Async</td><td>Buffered</td></tr>
<tr>
<td>Encoding → Notify</td><td>Sync</td><td>Unbuffered</td></tr>
</tbody>
</table>
</div><pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">uploader</span><span class="hljs-params">(file <span class="hljs-keyword">chan</span> &lt;- <span class="hljs-keyword">string</span>)</span></span>{
    files &lt;- <span class="hljs-string">"video1.mp4"</span>
    files &lt;- <span class="hljs-string">"video2.mp4"</span>
    <span class="hljs-built_in">close</span>(files)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">encoder</span><span class="hljs-params">(file &lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>, processed <span class="hljs-keyword">chan</span> &lt;- <span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-keyword">for</span> file := files {
        processed &lt;- file + <span class="hljs-string">"encoded"</span>
    }
    <span class="hljs-built_in">close</span>(processed)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">notifier</span><span class="hljs-params">(processed &lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-keyword">for</span> p := <span class="hljs-keyword">range</span> processed {
        fmt.Println(<span class="hljs-string">"Notify user:"</span>,p)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    files := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>, <span class="hljs-number">10</span>) <span class="hljs-comment">// buffered queue of uploaded videos</span>
    processed := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)

    <span class="hljs-keyword">go</span> uploader(files)
    <span class="hljs-keyword">go</span> encoder(files,processed)
    notifier(processed)
}
</code></pre>
<h2 id="heading-faq-interview-focused">FAQ (Interview - Focused)</h2>
<ol>
<li><p><strong>Why do we need channels if we have goroutine?</strong>  </p>
<p> Because goroutines run independently. Channels allow safe communication and synchronization without mutex locks.  </p>
</li>
<li><p><strong>Are channels thread-safe?</strong>  </p>
<p> YES. Channels are fully managed by GO runtime.  </p>
</li>
<li><p><strong>When to use buffered vs unbuffered channels?</strong>  </p>
<p> Unbuffered → synchronization<br /> Buffered = Improve throughput / decouple sender &amp; receiver  </p>
</li>
<li><p><strong>Is closing a channel mandatory ?</strong></p>
</li>
</ol>
<p>    No. Only needed to signal “no more values will come“. Receivers can range over it.  </p>
<ol start="5">
<li><p><strong>Can a closed channel still send data?</strong>  </p>
<p> No → panic.  </p>
</li>
<li><p><strong>Is it safe to read from a closed channel?  
 </strong><br /> Yes. You ge the remaining buffered values and then zero-value.  </p>
</li>
<li><p><strong>Can we close a receive-only channel?</strong>  </p>
<p> <strong>No. Only senders should close channels.</strong>  </p>
</li>
<li><p>Are channels FIFO?  </p>
<p> Yes. Go guarantees that channels are FIFO.  </p>
</li>
<li><p><strong>When should I use buffed channels?</strong>  </p>
<p> <strong>Use buffered channels when:</strong></p>
<ul>
<li><p>You need async processing.</p>
</li>
<li><p>Producers are faster than consumers.</p>
</li>
<li><p>Minor queueing is okay.</p>
</li>
<li><p>You want rate-limiting or batching</p>
</li>
</ul>
</li>
<li><p><strong>When should I use unbuffered channels?</strong>  </p>
<p><strong>Use unbuffered when:</strong></p>
<ul>
<li><p>You need strict hand-off</p>
</li>
<li><p>Sync between two goroutines</p>
</li>
<li><p>Avoid queueing.</p>
</li>
</ul>
</li>
<li><p>How to avoid goroutine leaks?</p>
<ul>
<li><p>Always close channels when done</p>
</li>
<li><p>Use context.Context</p>
</li>
<li><p>Avoid infinite blocking receives.  </p>
</li>
</ul>
</li>
<li><p><strong>Does reading from a nil channel block?</strong></p>
</li>
</ol>
<p>    Yes.</p>
<pre><code class="lang-go">    <span class="hljs-keyword">var</span> ch <span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span> <span class="hljs-comment">// nil</span>
    &lt;-ch            <span class="hljs-comment">// blocks forever</span>
</code></pre>
<ol start="13">
<li><p><strong>What happens if no one receives from an unbuffered channel?</strong>  </p>
<p>Sending goroutine blocks forever leads to deadlock.</p>
<pre><code class="lang-go">ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
ch &lt;- <span class="hljs-number">10</span> <span class="hljs-comment">// &lt;— deadlock: nobody is receiving</span>
</code></pre>
</li>
<li><p><strong>Does closing a channel stop goroutines?</strong>  </p>
<p>No. Closing a channel only means:</p>
<ul>
<li><p>No more sends allowed.</p>
</li>
<li><p>Receives will still return value until buffer empties.</p>
</li>
<li><p>After that, receives return the zero value</p>
</li>
</ul>
</li>
</ol>
<p>    Goroutines don’t stop automatically you must explicitly handle it.  </p>
<ol start="15">
<li><p><strong>Buffered vs Unbuffered — Performance difference ?</strong></p>
<ul>
<li><p>Unbuffered channels → slow because sender + receiver must meet</p>
</li>
<li><p>Buffered channels → faster (asynchronous, less blocking)</p>
</li>
</ul>
</li>
<li><p><strong>Can I detect if a channel is full or empty?</strong>  </p>
<p>No. Go intentionally hides this to avoid race conditions. You must structure your program so you don’t need to check this.</p>
</li>
<li><p>Can channels replace queues or message brokers ?</p>
<p>For small-scale in-memory concurrency, yes. For distributed systems, no.</p>
<p>Channels are</p>
<ul>
<li><p>In-memory</p>
</li>
<li><p>Single-process</p>
</li>
<li><p>Fast</p>
</li>
<li><p>Lightweight</p>
</li>
</ul>
</li>
</ol>
<p>    But they cannot repleace kafka, RabbitMQ, NATS, REDIS streams<br />    Use channels for in-process pipelines only.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Channels are one of Go’s most powerful concurrency features. They provide safe communication built-in synchronization, and easy coordination between goroutines without locks. Once you master channels, you unlock the real power of Go’s concurrency model.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding the fmt Package in GO]]></title><description><![CDATA[The fmt package is one of the most fundamental and frequently used packages in Go. Whether you’re printing values, formatting strings, scanning input, or even wrapping errors — fmt is everywhere.
Because of its importance, the fmt package is also a c...]]></description><link>https://blog.rohitlokhande.in/understanding-the-fmt-package-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/understanding-the-fmt-package-in-go</guid><category><![CDATA[fmt package]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[fmt ]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Sun, 30 Nov 2025 06:12:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764482993197/d5c4412e-9c94-4c00-8568-89f362744b4a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The fmt package is one of the most fundamental and frequently used packages in Go. Whether you’re printing values, formatting strings, scanning input, or even wrapping errors — fmt is everywhere.</p>
<p>Because of its importance, the fmt package is also a common topic in Go interviews, especially around formatting verbs, stringers, and error wrapping.</p>
<p>In this article, we’ll explore:</p>
<ul>
<li><p>What the fmt package does</p>
</li>
<li><p>Printing functions</p>
</li>
<li><p>Formatting verbs</p>
</li>
<li><p>Creating formatted strings</p>
</li>
<li><p>Scanning input</p>
</li>
<li><p>Working with writers (<code>Fprint</code>, <code>Fprintln</code>, <code>Fprintf</code>)</p>
</li>
<li><p>Error wrapping using <code>fmt.Errorf</code></p>
</li>
<li><p>Implementing the <code>fmt.Stringer</code> interface</p>
</li>
<li><p>Width, padding &amp; precision</p>
</li>
<li><p>Struct, slice &amp; map formatting</p>
</li>
<li><p>A complete example</p>
</li>
</ul>
<p>This article is ideal for beginners, intermediate developers, and anyone preparing for Go interviews.</p>
<h2 id="heading-what-is-the-fmt-package">What Is the fmt Package?</h2>
<p>The <code>fmt</code> package provides a set of functions for:</p>
<ul>
<li><p>Formatted output (printing)</p>
</li>
<li><p>Formatted input (scanning)</p>
</li>
<li><p>Working with strings</p>
</li>
<li><p>Working with I/O streams</p>
</li>
<li><p>Error creation &amp; wrapping</p>
</li>
</ul>
<p>Import it using:</p>
<pre><code class="lang-go"><span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
</code></pre>
<p>Let’s explore everything in detail.</p>
<h2 id="heading-printing-in-go-using-fmt">Printing in Go using fmt</h2>
<h3 id="heading-fmtprintln-print-with-newline"><code>fmt.Println()</code> — Print with newline</h3>
<pre><code class="lang-go">fmt.Println(<span class="hljs-string">"Hello"</span>, <span class="hljs-string">"World"</span>)
</code></pre>
<p>Output</p>
<pre><code class="lang-bash">Hello World
</code></pre>
<h3 id="heading-fmtprint-print-without-newline"><code>fmt.Print()</code> — Print without newline</h3>
<pre><code class="lang-go">fmt.Print(<span class="hljs-string">"Hello "</span>)
fmt.Print(<span class="hljs-string">"World"</span>)
</code></pre>
<h3 id="heading-fmtprintf-formatted-output"><code>fmt.Printf()</code> — Formatted output</h3>
<p>Uses formatting verbs like <code>%s</code>, <code>%d</code>, <code>%v</code>, etc.</p>
<pre><code class="lang-go">name := <span class="hljs-string">"Rohit"</span>
age := <span class="hljs-number">24</span>

fmt.Printf(<span class="hljs-string">"My name is %s and I am %d year old\n"</span>, name,age)
</code></pre>
<h2 id="heading-important-fmt-format-verbs">Important <code>fmt</code> Format Verbs</h2>
<p><strong>General Verbs</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Verb</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td>%v</td><td>Default format</td></tr>
<tr>
<td>%+v</td><td>Shows struct field names</td></tr>
<tr>
<td>%#v</td><td>Go-syntax representation</td></tr>
<tr>
<td>%T</td><td>Prints the type</td></tr>
</tbody>
</table>
</div><p>Example:</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>
}

u := User{<span class="hljs-string">"Rohit"</span>,<span class="hljs-number">24</span>}

fmt.Printf(<span class="hljs-string">"%v\n"</span>,u) <span class="hljs-comment">// Default format</span>
fmt.Printf(<span class="hljs-string">"%+v/n"</span>,u) <span class="hljs-comment">// Show struct field names</span>
fmt.Printf(<span class="hljs-string">"%#v\n"</span>,u) <span class="hljs-comment">// Go-syntax representation</span>
fmt.Printf(<span class="hljs-string">"%T\n"</span>,u) <span class="hljs-comment">// Prints the type</span>
</code></pre>
<p><strong>String Verbs</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Verb</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td>%s</td><td>String</td></tr>
<tr>
<td>%q</td><td>Quoted string</td></tr>
<tr>
<td>%x</td><td>Hex format</td></tr>
</tbody>
</table>
</div><p>Number verbs</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Verb</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td>%d</td><td>Integer</td></tr>
<tr>
<td>%f</td><td>Float</td></tr>
<tr>
<td>%b</td><td>Binary</td></tr>
<tr>
<td>%t</td><td>Boolean</td></tr>
</tbody>
</table>
</div><h2 id="heading-building-strings-instead-of-printing">Building Strings Instead of Printing</h2>
<p>Use the <code>Sprintf</code> family when you want to create a string instead of printing it.</p>
<h3 id="heading-fmtsprintf">fmt.Sprintf</h3>
<pre><code class="lang-go">msg := fmt.Sprintf(<span class="hljs-string">"Hi %s, score: %d"</span>,<span class="hljs-string">"Rohit"</span>,<span class="hljs-number">90</span>)
fmt.Println(msg)
</code></pre>
<h2 id="heading-writing-to-files-buffers-amp-http-responses-fprint-fprintf-fprintln">Writing to Files, Buffers &amp; HTTP Responses — <code>Fprint</code>, <code>Fprintf</code>, <code>Fprintln</code></h2>
<p>These functions write to any <code>io.Writer</code>, not just stdout.</p>
<p>Example: Writing to a file</p>
<pre><code class="lang-go">file,_ := os.Create(<span class="hljs-string">"outout.txt"</span>)
fmt.Fprintf(file,<span class="hljs-string">"Hello %s!"</span>, <span class="hljs-string">"Rohit"</span>)
</code></pre>
<p>This is widely used in</p>
<ul>
<li><p>Web servers (http.ResponseWriter)</p>
</li>
<li><p>Logging systems</p>
</li>
<li><p>Buffers</p>
</li>
<li><p>Files</p>
</li>
</ul>
<h2 id="heading-reading-input-scan-scanin-scanf">Reading Input — Scan ScanIn, Scanf</h2>
<h3 id="heading-fmtscan-space-separated-input">fmt.Scan — space-separated input</h3>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> name <span class="hljs-keyword">string</span>
<span class="hljs-keyword">var</span> age <span class="hljs-keyword">int</span>
fmt.Scan(&amp;name,&amp;age)
</code></pre>
<h3 id="heading-fmtscanin-stops-at-newline">fmt.ScanIn (stops at newline)</h3>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> city <span class="hljs-keyword">string</span>
fmt.Scanln(&amp;city)
</code></pre>
<h3 id="heading-fmtscanf-formatted-input">fmt.Scanf (formatted input)</h3>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> name <span class="hljs-keyword">string</span>
<span class="hljs-keyword">var</span> age <span class="hljs-keyword">int</span>
fmt.Scanf(<span class="hljs-string">"%s %d"</span>,&amp;name,&amp;age)
</code></pre>
<h2 id="heading-error-handling-with-fmterrorf">Error Handling with fmt.Errorf</h2>
<h3 id="heading-creating-errors">creating errors</h3>
<pre><code class="lang-go">err := fmt.Errorf(<span class="hljs-string">"invalid input"</span>)
</code></pre>
<h3 id="heading-wrapping-errors-using-w">Wrapping errors using <code>%w</code></h3>
<pre><code class="lang-go">err := fmt.Errorf(<span class="hljs-string">"db error: %w"</span>, originalErr)
</code></pre>
<p>Then unwrap</p>
<pre><code class="lang-go">errors.Is(err,originalErr)
</code></pre>
<p>I have explained this error handling in detail in this article → <a target="_blank" href="https://blog.rohitlokhande.in/error-handling-in-go">https://blog.rohitlokhande.in/error-handling-in-go</a></p>
<h2 id="heading-implementing-fmtstringer-customize-struct-printing">Implementing fmt.Stringer — Customize Struct Printing</h2>
<p><code>fmt.Stringer</code> is an interface</p>
<pre><code class="lang-plaintext">type Stringer interface {
    String() string
}
</code></pre>
<p>Implement it on your struct:</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-params">(u User)</span> <span class="hljs-title">String</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"User(Name=%s, Age=%d)"</span>,u.Name, u.Age)
}
<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">"Rohit"</span>, <span class="hljs-number">24</span>}
    fmt.Println(u)
}
</code></pre>
<pre><code class="lang-go">User(Name=Rohit, Age=<span class="hljs-number">24</span>)
</code></pre>
<h2 id="heading-formatting-width-alignmentpadding-amp-precision">Formatting Width, Alignment,Padding &amp; Precision</h2>
<h3 id="heading-width">Width</h3>
<pre><code class="lang-go">fmt.Printf(<span class="hljs-string">"|%10s|\n"</span>, <span class="hljs-string">"Go"</span>) <span class="hljs-comment">// right-aligned</span>
fmt.Printf(<span class="hljs-string">"|%-10s|\n"</span>,<span class="hljs-string">"Go"</span>) <span class="hljs-comment">// left-aligned</span>
</code></pre>
<h3 id="heading-zero-padding">Zero-padding</h3>
<pre><code class="lang-go">fmt.Printf(<span class="hljs-string">"%05d\n"</span>,<span class="hljs-number">42</span>) <span class="hljs-comment">// 00042</span>
</code></pre>
<h3 id="heading-floating-precision">Floating precision</h3>
<pre><code class="lang-go">fmt.Printf(<span class="hljs-string">"%.2f\n"</span>,<span class="hljs-number">3.14159</span>) <span class="hljs-comment">// 3.14</span>
</code></pre>
<h2 id="heading-formatting-structs-maps-slices">Formatting Structs, Maps, Slices</h2>
<pre><code class="lang-go">user := <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>{<span class="hljs-string">"name"</span>:<span class="hljs-string">"Rohit"</span>}
fmt.Printf(<span class="hljs-string">"Map:%+v\n"</span>,user)
</code></pre>
<p>Output</p>
<pre><code class="lang-bash">Map:map[name:Rohit]
</code></pre>
<h2 id="heading-using-fmt-with-buffers-iowriter">Using fmt With Buffers (io.Writer)</h2>
<h3 id="heading-what-is-buffer">What is Buffer?</h3>
<p>A buffer is a temporary storage area in memory used to hold data before it is processed, written, or read.</p>
<p>Think of a buffer like a bucket.</p>
<ul>
<li><p>You collect some data in the bucket (buffer).</p>
</li>
<li><p>Once enough data is collected or when ready, you pour it out (write it somewhere).</p>
</li>
<li><p>This avoids sending small pieces one by one.</p>
</li>
</ul>
<p>Buffers help make input/output operations faster and more efficient.</p>
<h3 id="heading-why-do-we-need-buffers">Why Do We Need Buffers?</h3>
<p>Because reading or writing small amounts of data very frequently is slow.</p>
<p>Example:</p>
<ul>
<li><p>Writing to a file every time you add a character will slow down the process.</p>
</li>
<li><p>Instead, write to a buffer in memory and then flush it to a file in larger chunks. This speeds up the process.</p>
</li>
</ul>
<pre><code class="lang-go"><span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>;
    <span class="hljs-string">"bytes"</span>
 )
<span class="hljs-keyword">var</span> b bytes.Buffer
fmt.Fprintln(&amp;b,<span class="hljs-string">"Hello Buffer"</span>)
fmt.Println(<span class="hljs-string">"Buffer content:"</span>,b.String())
</code></pre>
<p>We have covered the basic concepts of the fmt package, which are widely used. There are also some less common but useful concepts that we will explore further.</p>
<h2 id="heading-fmtgostringer-interface"><code>fmt.GoStringer</code> Interface</h2>
<p><code>fmt.GoStringer</code> is an interface similar to <code>fmt.Stringer</code>, but it is used when formatting a type using:</p>
<ul>
<li><p><code>%#v</code> (Go-syntax representation)</p>
</li>
<li><p><code>fmt.GoString()</code></p>
</li>
</ul>
<p>Interface definition:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> GoStringer <span class="hljs-keyword">interface</span> {
    GoString() <span class="hljs-keyword">string</span>
}
</code></pre>
<p>If your type implements <code>GoString()</code> string, then <code>%#v</code> will call your custom method.</p>
<p>Example:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<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-comment">// Implementing GoStringer</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(u User)</span> <span class="hljs-title">GoString</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"User{Name: %q, Age: %d}"</span>, u.Name, u.Age)
}

<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">"Rohit"</span>, <span class="hljs-number">24</span>}

    fmt.Println(<span class="hljs-string">"Normal print:"</span>)
    fmt.Println(u) <span class="hljs-comment">// does NOT use GoString</span>

    fmt.Println(<span class="hljs-string">"\nGo-syntax print using %#v:"</span>)
    fmt.Printf(<span class="hljs-string">"%#v\n"</span>, u) <span class="hljs-comment">// uses GoString()</span>
}
</code></pre>
<p>Output</p>
<pre><code class="lang-bash">Normal <span class="hljs-built_in">print</span>:
{Rohit 24}

Go-syntax <span class="hljs-built_in">print</span> using %<span class="hljs-comment">#v:</span>
User{Name: <span class="hljs-string">"Rohit"</span>, Age: 24}
</code></pre>
<h3 id="heading-what-happening-here">What happening here?</h3>
<p><code>fmt.Println(u)</code> → Uses the default structure formatting because we did not implement Stringer.</p>
<p><code>fmt.Printf("%#v", u)</code> → Now Go sees that User implements the <code>GoString() string</code> method, so it prints the custom Go-like struct representation.</p>
<h3 id="heading-why-do-we-need-gostring">Why do we need GoString?</h3>
<p>fmt.Stringer is for human-readable output.</p>
<p>fmt.GoStringer is for debugging, logging, and developer-friendly Go syntax output.</p>
<h2 id="heading-fmtappendf-append-appendln">fmt.Appendf, Append, Appendln</h2>
<p>These functions were added to Go to make it easier to append formatted data to a byte slice without using a <code>bytes.Buffer</code> or <code>strings.Builder</code>.</p>
<p>That means instead of</p>
<pre><code class="lang-go">b := []<span class="hljs-keyword">byte</span>{}
b = <span class="hljs-built_in">append</span>(b,fmt.Sprintf(<span class="hljs-string">"Hello %s"</span>,name))
</code></pre>
<p>You can directly do:</p>
<pre><code class="lang-go">b = fmt.Appendf(b, <span class="hljs-string">"Hello %s"</span>, name)
</code></pre>
<h3 id="heading-fmtappend"><code>fmt.Append</code></h3>
<ul>
<li><p>Similar to <code>fmt.Sprint</code>.</p>
</li>
<li><p>Converts arguments to string form.</p>
</li>
<li><p>Appends to a byte slice,</p>
</li>
<li><p>No formatting verbs required.</p>
</li>
</ul>
<p>Example</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    b := []<span class="hljs-keyword">byte</span>(<span class="hljs-string">"Start: "</span>)
    b = fmt.Append(b,<span class="hljs-string">"Hello"</span>,<span class="hljs-string">" "</span>,<span class="hljs-number">124</span>)
    fmt.Println(<span class="hljs-keyword">string</span>(b))
}
</code></pre>
<p>Output</p>
<pre><code class="lang-bash">Start: Hello 123
</code></pre>
<h3 id="heading-fmtappendln"><code>fmt.Appendln</code></h3>
<ul>
<li><p>Similar to <code>fmt.Sprintln</code>.</p>
</li>
<li><p>Appends arguments with spaces and a newline</p>
</li>
</ul>
<p>Example</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    b := []<span class="hljs-keyword">byte</span>{}
    b = fmt.Appendln(b,<span class="hljs-string">"Hello"</span>,<span class="hljs-string">"world"</span>)
    b = fmt.Appendln(b,<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>)
    fmt.Println(<span class="hljs-keyword">string</span>(b))
}
</code></pre>
<p>Output</p>
<pre><code class="lang-bash">Hello World
10 20 30
</code></pre>
<h3 id="heading-fmtappendf"><code>fmt.Appendf</code></h3>
<ul>
<li><p>Similar to <code>fmt.Sprintf</code></p>
</li>
<li><p>You can use formatting verbs (<code>%d</code>,<code>%s</code>,<code>%v</code> etc)</p>
</li>
</ul>
<p>Example</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    b := []<span class="hljs-keyword">byte</span>(<span class="hljs-string">"User: "</span>)

    b = fmt.Appendf(b, <span class="hljs-string">"%s (%d years old)"</span>, <span class="hljs-string">"Rohit"</span>, <span class="hljs-number">25</span>)

    fmt.Println(<span class="hljs-keyword">string</span>(b))
}
</code></pre>
<p>Output</p>
<pre><code class="lang-bash">User: Rohit (25 years old)
</code></pre>
<h3 id="heading-when-to-use-append-functions">When to Use Append Functions?</h3>
<p>These functions are useful when:</p>
<ul>
<li><p>You want zero allocation or minimal memory overhead.</p>
</li>
<li><p>You want a lightweight alternative to <code>bytes.Buffer</code>.</p>
</li>
<li><p>You want to efficiently build output in a byte slice.</p>
</li>
<li><p>High-performance systems (servers, loggers, serializers).</p>
</li>
</ul>
<h2 id="heading-faq-frequently-asked-questions-about-gos-fmt-package">FAQ: Frequently Asked Questions About Go’s fmt Package</h2>
<ol>
<li><p><strong>What is the fmt package used for in Go?</strong></p>
<p> The fmt package is used for formatted I/O operations such as printing to the console, formatting strings, scanning input, and writing to buffers or byte slices. It provides functions like <code>Println</code>, <code>Printf</code>, <code>Sprintf</code>, <code>Scan</code>, and more.</p>
</li>
<li><p><strong>What is the difference between</strong> <code>Print</code><strong>,</strong> <code>Println</code><strong>, and</strong> <code>Printf</code><strong>?</strong></p>
</li>
</ol>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Function</td><td>Behavior</td></tr>
</thead>
<tbody>
<tr>
<td>Print</td><td>Prints values without newline or formatting</td></tr>
<tr>
<td>Println</td><td>Prints values separated by spaces + automatically adds newline</td></tr>
<tr>
<td>Printf</td><td>Prints formatted output using verbs like <code>%s</code>, <code>%d</code>, <code>%v</code></td></tr>
</tbody>
</table>
</div><ol start="3">
<li><p><strong>What are formatting verbs in fmt?</strong></p>
<p> Formatting verbs are special placeholders (e.g., %d, %s, %v) used to format data.</p>
<p> Example:</p>
<ul>
<li><p>%s → string</p>
</li>
<li><p>%d → integer</p>
</li>
<li><p>%f → float</p>
</li>
<li><p>%v → value in default format</p>
</li>
</ul>
</li>
</ol>
<ol start="4">
<li><p><strong>What is</strong> <code>fmt.Stringer</code> <strong>and why is it important</strong></p>
<p> <code>fmt.Stringer</code> is an interface with the method → <code>String() string</code>.<br /> If a type implements this method, fmt uses it to decide how that type should be printed.<br /> This is very helpful in debugging and logging.</p>
</li>
<li><p><strong>What is</strong> <code>fmt.GoStringer</code><strong>?</strong></p>
<p> <code>fmt.GoStringer</code> is an interface for generating Go-syntax-friendly output.</p>
<p> It uses the <code>GoString() string</code> interface.</p>
<p> This result is used when formatting with <code>%#v</code>.</p>
</li>
<li><p><strong>What’s the difference between bus := bytes.Buffer{} and using fmt functions?</strong></p>
</li>
</ol>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Approach</td><td>Best Use Case</td></tr>
</thead>
<tbody>
<tr>
<td>bytes.Buffer</td><td>High-Performace string building, especially in loops</td></tr>
<tr>
<td>fmt.Sprint / fmt.Sprintf</td><td>Readable formatting, convenient, but more allocations</td></tr>
<tr>
<td>fmt.Append* functions</td><td>Fast, allocation-free appending to byte slices.</td></tr>
</tbody>
</table>
</div><ol start="7">
<li><p><strong>What are fmt.Append, Appendf, and Appendln ?</strong></p>
<p> These functions append formatted data directly to a byte slice.</p>
<ul>
<li><p>Append → like Sprint</p>
</li>
<li><p>Appendln → like Sprintln</p>
</li>
<li><p>Appendf → like Sprintf</p>
</li>
</ul>
</li>
</ol>
<p>    They are faster and avoid extra allocations, making them useful in logging or serialization.</p>
<ol start="8">
<li><p><strong>Is fmt package slow compared other manual string concatenation?</strong></p>
<p> fmt is extremely optimised, but</p>
<ul>
<li><p>It is slower than direct concatenation (+)</p>
</li>
<li><p>It is slower than strings.Builder</p>
</li>
<li><p>It is slower than bytes.Buffer</p>
</li>
</ul>
</li>
</ol>
<p>    However, it providers:</p>
<ul>
<li><p>cleaner code</p>
</li>
<li><p>safe formatting</p>
</li>
<li><p>powerful formatting verbs</p>
</li>
</ul>
<p>    For performance-critical sections, avoid using fmt in tight loops.</p>
<ol start="9">
<li><p><strong>What happens if formatting verbs don’t match the data type?</strong></p>
<p> fmt does not crash, unlike other languages. Instead, it prints a fallback format.</p>
<p> Example:</p>
<pre><code class="lang-go"> fmt.Printf(<span class="hljs-string">"%d"</span>,<span class="hljs-string">"hello"</span>)
</code></pre>
<pre><code class="lang-bash"> %!d(string=hello)
</code></pre>
</li>
</ol>
<ol start="10">
<li><p><strong>Can fmt print coloured output?</strong></p>
<p>No. fmt does not support ANSI colors. Use third-party libraries such as</p>
<ul>
<li><p><a target="_blank" href="http://github.com/fatih/color">github.com/fatih/color</a></p>
</li>
<li><p><a target="_blank" href="http://github.com/mgutz/ansi">github.com/mgutz/ansi</a></p>
</li>
</ul>
</li>
<li><p><strong>Why should I implement String() for custom structs?</strong></p>
<p>Because:</p>
<ul>
<li><p>Your logs become cleaner</p>
</li>
<li><p>Your debugging becomes easier</p>
</li>
<li><p>fmt.Printf(“%v“) output readable data</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The fmt package is one of the first tools every Go developer learns—and for good reason. It simplifies printing, formatting, scanning, and working with different data types. From basic functions like Println to advanced features like Stringer, formatting verbs, and the new Append functions, fmt makes everyday coding much easier and more readable.</p>
<p>If you understand how fmt works, you can write cleaner logs, better debug your programs, and format data more effectively. It’s a small package, but it plays a big role in every Go project.</p>
]]></content:encoded></item><item><title><![CDATA[Goroutines: The Power Behind Go's Concurrency]]></title><description><![CDATA[If you’ve ever worked with Java threads, Python’s multiprocessing, or JavaScript async/await, you know that concurrency can be tricky.It’s either too complex, too heavy, or too unpredictable.
But then comes Go, with a fresh take—simple, efficient, an...]]></description><link>https://blog.rohitlokhande.in/goroutines-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/goroutines-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[goroutines]]></category><category><![CDATA[goroutine]]></category><category><![CDATA[multithreading in golang]]></category><category><![CDATA[concurrency-in-go]]></category><category><![CDATA[concurrency]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Tue, 18 Nov 2025 18:20:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763278773371/7e3440b5-4903-4871-a88d-7e861750d5f1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’ve ever worked with Java threads, Python’s multiprocessing, or JavaScript async/await, you know that concurrency can be tricky.<br />It’s either too complex, too heavy, or too unpredictable.</p>
<p>But then comes Go, with a fresh take—simple, efficient, and elegant concurrency.<br />The magic ingredient? Goroutines.</p>
<p>In this post, we’ll break down how goroutines work, how they differ from threads or processes, and why Go’s approach is a game-changer for modern developers.</p>
<p>Before diving into goroutines, let's first understand multithreading and multiprocessing. I have created a separate blog for this, so check it out before moving forward.</p>
<p>👉 <a target="_blank" href="https://blog.rohitlokhande.in/multiprocessing-vs-multithreading-understanding-concurrency-and-parallelism?showSharer=true">Multiprocessing vs Multithreading: Understanding Concurrency and Parallelism</a></p>
<p>If you've read that, let's move on to goroutines now.</p>
<h2 id="heading-what-are-goroutines">What Are Goroutines?</h2>
<p>A goroutine is a function that runs at the same time as other functions. You start one by adding the <code>go</code> keyword before a function call.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">printMessage</span><span class="hljs-params">(msg <span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">3</span>; i++ {
        fmt.Println(msg,i)
        time.Sleep(<span class="hljs-number">500</span> * time.Millisecond)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">go</span> printMessage(<span class="hljs-string">"Goroutine"</span>) <span class="hljs-comment">// run concurrently</span>
    printMessage(<span class="hljs-string">"Main Function"</span>)
}
</code></pre>
<p>Output (order may vary)</p>
<pre><code class="lang-bash">Main Funtion 1
Goroutine 1
Main Function 2
Goroutine 2
Main Function 3
Goroutine 3
</code></pre>
<p><strong>What’s happening here?</strong></p>
<ul>
<li><p>The main function runs in the "main goroutine."</p>
</li>
<li><p><code>go printMessage()</code> creates a new concurrent goroutine.</p>
</li>
<li><p>Both functions run concurrently — the interleaved output confirms that.</p>
</li>
</ul>
<h2 id="heading-how-goroutines-differ-from-multithreading-in-other-languages">How Goroutines Differ From Multithreading in Other Languages</h2>
<ol>
<li><p><strong>The core difference — who schedules work?</strong></p>
<p> <strong>Threads (Java/C++/pthreads):</strong></p>
<ul>
<li><p>Typically, there is a 1:1 mapping between a language thread and an OS thread.</p>
</li>
<li><p>The operating system kernel schedules threads onto CPU cores using its scheduler.</p>
</li>
<li><p>Creating a thread is relatively expensive — it involves memory and kernel bookkeeping.</p>
</li>
<li><p>The OS decides when to run, pause, or preempt each thread.</p>
</li>
</ul>
</li>
</ol>
<p>    <strong>Goroutines:</strong></p>
<ul>
<li><p>Go runtime uses a sophisticated work-stealing scheduler (M:N model) to distribute goroutines efficiently across the available CPU cores or OS threads maximising CPU utilisation and minimising the overhead of context switching.</p>
</li>
<li><p>The M:N model is a scheduling approach used by the Go runtime to efficiently manage many goroutines (M) with a smaller, fixed number of operating system threads (N).</p>
</li>
<li><p>In simple terms it’s like a team of highly adaptable workers (goroutines) sharing a fixed set of desks (OS threads) in an office.</p>
</li>
</ul>
<p>    Implication: Goroutines are extremely cheap to create and schedule compared to OS threads, allowing programs to scale to thousands or millions of concurrent tasks.</p>
<ol start="2">
<li><p><strong>Memory cost and stacks</strong></p>
<p> <strong>OS Threads:</strong></p>
<ul>
<li><p>Each thread usually reserves a relatively large stack — often 1MB or more depending on the platform.</p>
</li>
<li><p>Creating many threads can quickly exhaust memory.</p>
</li>
</ul>
</li>
</ol>
<p>    <strong>Goroutines:</strong></p>
<ul>
<li><p>Start with a tiny stack — on the order of a few KB.</p>
</li>
<li><p>Stacks grow and shrink dynamically as needed; the runtime transparently allocates a larger stack and copies frames.</p>
</li>
<li><p>Because each goroutine consumes far less memory initially, creating thousands is feasible.</p>
</li>
</ul>
<p>    <strong>Why this matters:</strong> Goroutines let you model many independent tasks without paying huge memory costs per task.</p>
<ol start="3">
<li><p><strong>Scheduling M:N work-stealing and GOMAXPROCS</strong></p>
<p> The M:N scheduling model in Go (many goroutines onto fewer OS threads) can be easily understood using a chef and kitchen analogy.</p>
<p> Imagine a busy restaurant kitchen with:</p>
<ul>
<li><p><strong>Many Recipes/Orders (M) = Goroutines:</strong> There are potentially thousands of incoming food orders (goroutines), each representing a task that needs to be completed.</p>
</li>
<li><p>A Few Stoves/Cooking Stations (N) = OS Threads (CPU cores): The kitchen only has a limited number of physical cooking stations or stoves (OS threads) where actual cooking (CPU work) can happen simultaneously.</p>
</li>
<li><p>The Head Chef = The Go Runtime Scheduler: A highly efficient head chef manages the flow of orders and assigns them to the available cooking stations.</p>
</li>
</ul>
</li>
</ol>
<p>    <strong>How the M:N Model Works</strong></p>
<ul>
<li><p><strong>Assigning Orders:</strong> The head chef gives an order to one of the assistant chefs at an empty cooking station.</p>
</li>
<li><p><strong>Handling “Waiting” (Blocking I/O):</strong> An assistant chef is working on a complex dish that requires 10 minutes to simmer unattended (a “blocking I/O” operation, like waiting for a database response).</p>
</li>
<li><p><strong>The Efficient Switch:</strong> The head chef immediately tells that assistant chef to step aside while the food simmers. The head chef then gives a new order to that now-empty cooking station. The original assistant chef returns to the station only when the 10 minutes are up and the dish needs attention again.</p>
</li>
<li><p><strong>Balancing Work:</strong> The head chef continuously monitors all stations, ensuring no station sits idle if there are orders waiting. If one station gets a backlog, the chef might even move orders to another, less busy station (work stealing).</p>
</li>
</ul>
<h3 id="heading-what-is-work-stealing">What is Work-Stealing?</h3>
<p>    Imagine 4 chefs (P1, P2, P3, P4), each with their own queue of tasks (Gs).</p>
<p>    If P1 finishes its work but P2 still has 20 tasks:</p>
<p>    P1 takes some goroutines from P2’s queue to balance the load.</p>
<p>    This keeps any CPU core from being idle.</p>
<p>    <strong>In simpler words:</strong></p>
<p>    Idle Ps take work from busy Ps to keep the CPU fully utilized.</p>
<h3 id="heading-what-is-gomaxprocs">What is GOMAXPROCS?</h3>
<p>    GOMAXPROCS(n) sets how many Ps exist — i.e., how many OS threads can run Go code at the same time.</p>
<p>    Default = number of CPU cores.</p>
<h3 id="heading-what-is-preemption">What is Preemption?</h3>
<p>    Imagine one task keeps running forever, like an infinite loop. Other tasks would never run unless Go can interrupt it. This is what preemption does: the scheduler interrupts a long-running goroutine to give others a turn. Because of this, no goroutine can hog the CPU forever.</p>
<h3 id="heading-real-world-example-concurrent-web-requests">Real-World Example — Concurrent Web Requests</h3>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"net/http"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetch</span><span class="hljs-params">(url <span class="hljs-keyword">string</span>)</span></span> {
    resp, err := http.Get(url)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error fetching:"</span>, url)
        <span class="hljs-keyword">return</span>
    }
    <span class="hljs-keyword">defer</span> resp.Body.Close()
    fmt.Println(url, <span class="hljs-string">"-&gt;"</span>,resp.Status)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    urls := []<span class="hljs-keyword">string</span>{
        <span class="hljs-string">"https://golang.org"</span>,
        <span class="hljs-string">"https://google.com"</span>,
        <span class="hljs-string">"https://github.com"</span>,
    }
    <span class="hljs-keyword">for</span> _, url := <span class="hljs-keyword">range</span> urls {
        <span class="hljs-keyword">go</span> fetch(url) <span class="hljs-comment">// fetch all concurrently</span>
    }
    fmt.Scanln() <span class="hljs-comment">// block main goroutine</span>
}
</code></pre>
<pre><code class="lang-bash">https://golang.org -&gt; 200 OK
https://google.com -&gt; 200 OK
https://github.com -&gt; 200 OK
</code></pre>
<ul>
<li><p>All three requests run concurrently</p>
</li>
<li><p>The program doesn't wait for one request to finish before starting another.</p>
</li>
<li><p>This is Go’s concurrency power — simple syntax, massive performance gain.</p>
</li>
</ul>
<p>Let’s understand this code using a kitchen analogy.</p>
<p>In this analogy:</p>
<ul>
<li><p><code>main()</code> function: The owner of the restaurant.</p>
</li>
<li><p><code>fetch()</code> function: A detailed recipe for preparing one specific dish (fetching a URL).</p>
</li>
<li><p><code>go fetch(url)</code>: Handling an order ticket to the head chef and asking for a dish to be prepared immediately.</p>
</li>
<li><p>The websites (golang.org, etc.): Suppliers with whom the kitchen must communicate.</p>
</li>
<li><p><code>fmt.Scanln()</code>: The restaurant owner waiting patiently at the counter until all orders are confirmed complete.</p>
</li>
</ul>
<ol>
<li><p><strong>Setting Up the Restaurant (The</strong> <code>main</code> <strong>function start)</strong></p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
     urls := []<span class="hljs-keyword">string</span>{
         <span class="hljs-string">"https://golang.org"</span>,
         <span class="hljs-string">"https://google.com"</span>,
         <span class="hljs-string">"https://github.com"</span>,
     }
     <span class="hljs-comment">// ...</span>
 }
</code></pre>
<p> The restaurant owner (the <code>main</code> function) writes down three specific orders on tickets: one for <code>golang.org</code> soup, one for <code>google.com</code> salad, and one for <code>github.com</code> steak.  </p>
</li>
<li><p><strong>Handling Off Orders to the Kitchen (The</strong> <code>go</code> <strong>keyword)</strong></p>
<pre><code class="lang-go"> <span class="hljs-keyword">for</span> _,url := <span class="hljs-keyword">range</span> urls {
     <span class="hljs-keyword">go</span> fetch(url) <span class="hljs-comment">// fetch all concurrently</span>
 }
</code></pre>
<p> The owner takes all three order tickets and hands them to the Head Chef (the Go Runtime Scheduler) simultaneously: “Start cooking all of these now!”</p>
<p> The <code>go</code> keyword is crucial here. It tells the head chef to use the M:N scheduling model:</p>
<ul>
<li><p>Each <code>fetch(url)</code> call becomes a separate recipe/order (goroutine).</p>
</li>
<li><p>The head chef immediately assigns these recipes to the available cooking stations (OS threads) in the kitchen.</p>
</li>
</ul>
</li>
<li><p><strong>Preparing a Single Dish (The fetch function)</strong></p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetch</span><span class="hljs-params">(url <span class="hljs-keyword">string</span>)</span></span> {
     resp, err := http.Get(url)
     <span class="hljs-comment">// ...</span>
 }
</code></pre>
<p> This is where the magic of the M:N model happens:</p>
<ul>
<li><p><strong>Calling the Supplier (</strong><code>http.Get(url)</code><strong>):</strong> The assistant chef at a cooking station starts preparing the dish but immediately finds they need a specific ingredient from a supplier (making a network request).</p>
</li>
<li><p><strong>The Head Chef Manages the Wait:</strong> The supplier is slow to respond (the network I/O is blocking). Instead of letting the assistant chef just stand there idly, blocking the entire cooking station, the Head Chef (Go Scheduler) switches them out.</p>
</li>
<li><p><strong>Efficient Kitchen Use:</strong> The original assistant chef goes to wait by the back door for the supplier delivery. The cooking station they were using is immediately assigned to another recipe that is ready for CPU work. This keeps all stations busy!</p>
</li>
<li><p><strong>Finishing the Dish (</strong><code>fmt.Println(…)</code><strong>):</strong> Once the supplier arrives with the data, the assistant chef returns to an available station and confirms the order status.<br />  (“<code>https://golang.org</code>“ → <code>200 OK</code>)</p>
</li>
</ul>
</li>
<li><p><strong>The Owner Waits for Confirmation (</strong><code>fmt.Scanln()</code><strong>)</strong></p>
<pre><code class="lang-go">  fmt.Scanln() <span class="hljs-comment">// block main goroutine</span>
</code></pre>
<p> This line is necessary because the restaurant owner (<code>main</code> function) needs to stay in the building until all three orders are confirmed and served.</p>
<p> Without this line, the owner would hand the tickets to the chef and immediately leave the restaurant, shutting everything down before the dishes are even started. (We are not using <code>fmt.Scanln()</code> here; there are other alternatives for this condition, which we will learn about later.)</p>
</li>
</ol>
<p>In this analogy</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Analogy Component</td><td>Techinical Term</td></tr>
</thead>
<tbody>
<tr>
<td>Recipes / Orders</td><td>Goroutines (M)</td></tr>
<tr>
<td>Cooking Stations/Stoves</td><td>OS Threads (N)</td></tr>
<tr>
<td>Head Chef / Expediter</td><td>Go Runtime Schedular</td></tr>
</tbody>
</table>
</div><p>And the assistant chefs are also part of the OS Threads (Cooking stations).</p>
<ul>
<li><p>OS Thread is the combination of the physical cooking station (the hardware resource) and the assistant chef working at it (the execution mechanism)</p>
</li>
<li><p>The Head Chef (Go Runtime Schedular) is the management layer above the assistant chefs, telling them which recipes (goroutines) to work on.</p>
</li>
</ul>
<h2 id="heading-multiprocessing-in-go">Multiprocessing in Go</h2>
<p>Go doesn’t provide true multiprocessing directly, but it achieves similar benefits using goroutines and OS threads. The Go runtime automatically schedules goroutines across multiple CPU cores using the GOMAXPROCS setting.</p>
<p>This means:</p>
<ul>
<li><p>Go can run goroutines in parallel on different CPU cores.</p>
</li>
<li><p>The runtime handles thread creation, scheduling, and load balancing for you.</p>
</li>
<li><p>Developers get parallel execution without manually managing processes or threads.</p>
</li>
</ul>
<p>So even though you don’t explicitly create “processes,” Go delivers multiprocessing-like performance through its efficient runtime scheduler.</p>
<h2 id="heading-faq-section">FAQ Section</h2>
<ol>
<li><p><strong>Are goroutines the same as threads?</strong></p>
<p> No. Goroutines are not OS threads. They are lightweight functions managed by the Go runtime scheduler. Multiple goroutines run on top of a smaller set of OS threads.</p>
</li>
<li><p><strong>How many goroutines can I run at once?</strong></p>
<p> Usually hundreds of thousands or even millions, depending on RAM. Threads cannot scale anywhere close to this.</p>
</li>
<li><p><strong>Does each goroutine use its own thread?</strong></p>
<p> No. Goroutines are multiplexed onto a pool of worker threads using Go’s M:N scheduler. Multiple goroutines share a single thread (not simultaneously, but with fast switching).</p>
</li>
<li><p><strong>Is Go single-threaded or multithreaded?</strong></p>
<p> Go is multithreaded under the hood. Your program uses multiple OS threads automatically; you don’t need to manage them.</p>
</li>
<li><p><strong>Are goroutines good for CPU-intensive tasks?</strong></p>
<p> Yes, but you must understand that all CPU-bound goroutines compete for CPU cores. For heavy CPU work, increasing runtime.GOMAXPROCS() may help.</p>
</li>
<li><p><strong>Do goroutines run in parallel?</strong></p>
<p> If your machine has multiple CPU cores, then yes, goroutines run in parallel. If not, they run concurrently (taking turns), but still efficiently.</p>
</li>
<li><p><strong>Why are goroutines so lightweight?</strong></p>
<p> Because they use:</p>
<ul>
<li><p>a tiny initial stack (2 KB).</p>
</li>
<li><p>dynamic stack resizing.</p>
</li>
<li><p>a user-space scheduler.</p>
</li>
<li><p>cooperative + async preemption.</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Goroutines make concurrency in Go simple, lightweight, and incredibly scalable. Instead of dealing with heavy OS threads, Go gives you tiny, fast goroutines managed by an efficient runtime scheduler. This allows you to run thousands or even millions of concurrent tasks with minimal memory and almost no complexity.</p>
<h2 id="heading-whats-next">What’s Next?</h2>
<p>Now that goroutines are clear, the next step is understanding how they communicate and synchronize.<br />Up next, we’ll cover:</p>
<ul>
<li><p>Channels - How goroutines safely exchange data</p>
</li>
<li><p>Select — handling multiple concurrent operations</p>
</li>
<li><p>WaitGroup &amp; Mutex - essential sync tools</p>
</li>
<li><p>Real patterns like worker pools and pipelines.</p>
</li>
</ul>
<p>This will complete your core understanding of Go’s concurrency model.</p>
]]></content:encoded></item><item><title><![CDATA[Multiprocessing vs Multithreading: Understanding Concurrency and Parallelism]]></title><description><![CDATA[In this "Go Deep with Golang" series, we have nearly covered all the fundamental topics necessary for a solid understanding of the language. Before we proceed to the next topic, which is Goroutines, it is crucial to first grasp the concepts of multip...]]></description><link>https://blog.rohitlokhande.in/multiprocessing-vs-multithreading-understanding-concurrency-and-parallelism</link><guid isPermaLink="true">https://blog.rohitlokhande.in/multiprocessing-vs-multithreading-understanding-concurrency-and-parallelism</guid><category><![CDATA[concur]]></category><category><![CDATA[multithreading]]></category><category><![CDATA[multiprocessing]]></category><category><![CDATA[Parallel Programming]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Sat, 15 Nov 2025 16:08:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763210167813/1be1514c-4c8b-40c8-97cc-4c1c4925a43b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this "Go Deep with Golang" series, we have nearly covered all the fundamental topics necessary for a solid understanding of the language. Before we proceed to the next topic, which is Goroutines, it is crucial to first grasp the concepts of multiprocessing and multithreading. Understanding these concepts will provide a strong foundation for learning about Goroutines.</p>
<p>When we talk about performance in programming, terms like concurrency, parallelism, multithreading, and multiprocessing often come up together. They sound similar, but they describe different ways of doing multiple things at once.</p>
<p>We’ll break down these concepts in depth—how they work, how they differ, and when to use each.</p>
<h2 id="heading-the-core-idea-doing-multiple-things-at-once">The Core Idea: Doing Multiple Things at Once</h2>
<p>Before diving into threads and processes, let's start with the core concept of doing more than one thing at the same time.</p>
<p>There are two main strategies to achieve this:</p>
<ul>
<li><p><strong>Concurrency:</strong></p>
<p>  Structuring your program so it can handle multiple tasks seemingly at the same time.</p>
</li>
<li><p><strong>Parallelism:</strong></p>
<p>  Actually executing multiple tasks simultaneously using multiple CPUs or cores.</p>
</li>
</ul>
<p>These two often overlap but are not the same thing.</p>
<h2 id="heading-concurrency-vs-parallelism-the-foundation">Concurrency vs Parallelism: The Foundation</h2>
<h3 id="heading-concurrency">Concurrency</h3>
<p>Concurrency means handling multiple tasks in overlapping time periods, not necessarily simultaneously.</p>
<p>Imagine a download manager that’s responsible for downloading five large files.<br />If your internet connection can only handle one download at a time, the manager might download a chunk from file 1, then switch to file 2, then file 3, and so on—cycling rapidly between them.</p>
<p>To you, it feels like all files are downloading at once, but in reality, the system is just switching quickly between tasks.</p>
<blockquote>
<p>Concurrency is about efficient task-switching.</p>
</blockquote>
<p>Even if only one task runs at any given moment, all of them make progress over time. In programming, concurrency.</p>
<p>In programming, concurrency is especially useful for I/O bound operations like making API calls, reading files, and waiting for network responses, where tasks spend most of their time waiting rather than computing.</p>
<h3 id="heading-parallelism">Parallelism</h3>
<p>Parallelism means doing multiple things truly at the same time.</p>
<p>Now, imagine that same download manager, but you have multiple network connections or threads, each downloading a file simultaneously.<br />In this case, all files are actively downloading in parallel, and there’s no switching involved.</p>
<blockquote>
<p>Parallelism is about simultaneous execution using multiple cores or processors.</p>
</blockquote>
<p>Parallelism is ideal for CPU-bound workloads, such as heavy computations like image rendering, large data processing, or complex simulations.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763090005695/c5ba4d31-aa62-4dc9-9bdc-b70a0e253161.png" alt class="image--center mx-auto" /></p>
<p>The image above illustrates that in concurrency, there is 1 chef (or 1 core) switching tasks back and forth. On the other hand, in parallelism, there are 3 different chefs (or 3 cores) working on different tasks at the same time.</p>
<h3 id="heading-what-is-multithreading">What is Multithreading?</h3>
<p>A thread is the smallest unit of execution within a process. By default, a program runs as a single main thread, executing code sequentially.<br />Using multithreading, we can create multiple threads that share the same memory space and work concurrently.</p>
<p>Example</p>
<p>Let’s say you’re building a web server in Go:</p>
<ul>
<li><p>One thread handles incoming HTTP requests.</p>
</li>
<li><p>Another logs data to a file.</p>
</li>
<li><p>A third manages background jobs.</p>
</li>
</ul>
<p>Each thread runs independently, yet all share access to the same data and memory.</p>
<h3 id="heading-advantages-of-multithreading">Advantages of Multithreading</h3>
<ul>
<li><p>Threads are lightweight and fast to create.</p>
</li>
<li><p>They share memory, making communication simple.</p>
</li>
<li><p>Perfect for I/O-bound tasks like handling multiple web requests.</p>
</li>
</ul>
<h3 id="heading-drawbacks-of-multithreading">Drawbacks of Multithreading</h3>
<ul>
<li><p>Shared memory can cause race conditions (two threads updating the same variable).</p>
</li>
<li><p>Requires synchronization mechanisms (mutexes, locks).</p>
</li>
<li><p>In some languages like Python, the Global Interpreter Lock limits true parallelism with threads.</p>
</li>
</ul>
<h2 id="heading-what-is-multiprocessing">What is Multiprocessing?</h2>
<p>Multiprocessing takes a different approach; it runs multiple processes, each with its own memory and interpreter instance. They don’t share memory space, so they’re fully isolated and can run on different CPU cores.</p>
<p>Example:<br />When exporting a video in tools like Premiere Pro, Final Cut, or FFmpeg, the renderer splits the video into chunks and processes them simultaneously on multiple CPU cores.<br /><strong>Why multiprocessing?</strong><br /><strong>Each chunk is CPU-heavy and independent. More cores = faster rendering.</strong></p>
<h3 id="heading-advantages-of-multiprocessing">Advantages of Multiprocessing</h3>
<ul>
<li><p>True parallel execution across multiple cores.</p>
</li>
<li><p>Each process has isolated memory, so there are no race conditions.</p>
</li>
<li><p>Great for CPU-intensive workloads.</p>
</li>
</ul>
<h3 id="heading-drawbacks">Drawbacks</h3>
<ul>
<li><p>More overhead for creating and managing processes.</p>
</li>
<li><p>Harder to share data (requires inter-process communication).</p>
</li>
<li><p>Inter-process communication is slower than thread communication.</p>
</li>
</ul>
<h2 id="heading-how-many-threads-can-you-spawn">How Many Threads Can You Spawn?</h2>
<p>This is one of the most misunderstood topics.<br />Developers try creating</p>
<ul>
<li><p>1000 threads</p>
</li>
<li><p>10000 threads</p>
</li>
</ul>
<p>And then wonder why the system slows down.</p>
<p>Let's break it down.</p>
<h3 id="heading-thread-creation-depends-on-2-things">Thread Creation Depends on 2 Things</h3>
<ol>
<li><p><strong>Memory</strong></p>
<p> Each thread needs its own stack.</p>
<p> Default stack size:</p>
<ul>
<li><p>Linux: 8 MB</p>
</li>
<li><p>Windows: 1 MB</p>
</li>
<li><p>Java: 1 MB</p>
</li>
<li><p>Python: 8 MB</p>
</li>
<li><p>Go Goroutines: 2 kB</p>
</li>
</ul>
</li>
<li><p><strong>OS Thread Limit</strong></p>
<p> Linux allows tens of thousands of threads<br /> Windows/macOS allow fewer (2000 - 10000)</p>
</li>
</ol>
<h3 id="heading-max-threads-formula">Max Threads Formula</h3>
<pre><code class="lang-plaintext">Max Threads = Total Memory / Thread Stack Size
</code></pre>
<p>Example:<br />If you have 32 GB RAM and threads require 8 MB stack</p>
<pre><code class="lang-plaintext">32768 MB / 8 MB = 4,096 threads
</code></pre>
<p>So theoretically you could spawn nearly 4000 threads.<br />But you should not.</p>
<h3 id="heading-why-you-shouldnt-spawn-thousands-of-threads">Why You Shouldn’t Spawn Thousands of Threads</h3>
<ul>
<li><p>Context switching</p>
</li>
<li><p>Cache invalidation</p>
</li>
<li><p>CPU time slice overhead</p>
</li>
<li><p>Kernel thrashing</p>
</li>
</ul>
<p>Beyond a certain point, more threads lead to worse performance.</p>
<h2 id="heading-how-many-threads-should-you-spawn">How Many Threads Should You Spawn?</h2>
<h3 id="heading-cpu-bound-tasks">CPU-Bound Tasks</h3>
<p>Example</p>
<ul>
<li><p>Image processing</p>
</li>
<li><p>Compression</p>
</li>
<li><p>Encryption</p>
</li>
<li><p>Encoding</p>
</li>
</ul>
<p>Optimal threads = number of CPU cores<br />If you have 8 cores → 8 threads.</p>
<p>More threads won’t increase speed.</p>
<h3 id="heading-io-bound-tasks">I/O Bound Tasks</h3>
<p>Example</p>
<ul>
<li><p>API calls</p>
</li>
<li><p>DB queries</p>
</li>
<li><p>File reading</p>
</li>
<li><p>Network operations</p>
</li>
</ul>
<p>Threads spend most of the time waiting, so you can use many more.</p>
<p>Formula:</p>
<pre><code class="lang-plaintext">Optimal threads = Cores * (1 + (IO wait / compute time))
</code></pre>
<p>Example:<br />Task waits 90% of the time</p>
<pre><code class="lang-plaintext">8 cores * (1 + 0.9/0.1) = 80 threads
</code></pre>
<h3 id="heading-real-example-web-scraper">Real Example: Web Scraper</h3>
<p>Scraping 5000 URLs</p>
<ul>
<li><p>CPU usage is low</p>
</li>
<li><p>Network wait is high</p>
</li>
</ul>
<p>In this scenario, you can safely create 100-300 threads, or in Go, you can create 10,000+ goroutines.</p>
<p>Let's explore multithreading further by looking at real-world scenarios, such as how the system will perform when we run a "Reading 100 files" operation using a single thread versus multithreading.</p>
<p>Let’s say you write a program that needs to read 100 files from disk.</p>
<p>Reading a file is usually I/O-bound because:</p>
<ul>
<li><p>The thread asks the OS: “Please fetch file contents.”</p>
</li>
<li><p>The OS works with storage hardware.</p>
</li>
<li><p>The thread waits for disk I/O to finish.</p>
</li>
</ul>
<p>So the real difference between single-threading and multithreading becomes HUGE.</p>
<h2 id="heading-using-single-thread">Using Single Thread</h2>
<p>In a single-threaded program:</p>
<ol>
<li><p>The thread starts reading File 1</p>
</li>
<li><p>It waits for the disk to respond</p>
</li>
<li><p>When done, it moves to File 2</p>
</li>
<li><p>Waits again</p>
</li>
<li><p>File 3</p>
</li>
<li><p>Waits again</p>
</li>
</ol>
<p>This is repeated for all 100 files. Only one file is being processed at any moment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763191868589/d14ab825-8794-4135-b1a6-b09b05fe12fb.png" alt class="image--center mx-auto" /></p>
<p>In the diagram above, using a single-thread approach, the thread is blocked and cannot do anything else during the wait time. Files are processed one after another.</p>
<p>This is simple but slow.</p>
<h2 id="heading-using-multithreading">Using Multithreading</h2>
<p>Now suppose we create 10 threads to read 100 files.</p>
<p>Each thread gets 10 files. So instead of reading files one by one, it reads like  </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763197273509/591e2eff-e2a4-4f74-8550-2273aa65cba0.png" alt class="image--center mx-auto" /></p>
<p>In this,</p>
<ul>
<li><p>while Thread 1 waits for File 1, Thread 2 reads File 2.</p>
</li>
<li><p>Thread 3 reads File 3, and so on.</p>
</li>
</ul>
<p>So 10 files are being fetched I/O parallel, even on a single core — because disk I/O waits do not block other threads.</p>
<h3 id="heading-how-they-look-in-real-performance-terms">How They Look in Real Performance Terms</h3>
<p><strong>Single Thread</strong></p>
<pre><code class="lang-plaintext">Total time = (Time to read 1 file) * 100
</code></pre>
<p><strong>10 Threads</strong></p>
<pre><code class="lang-plaintext">Total time = (Time to read 10 files in parallel batches)
</code></pre>
<p>If reading 1 file takes 30ms:</p>
<ul>
<li><p>Single thread → 100 × 30ms = 3,000 ms</p>
</li>
<li><p>10 threads → (100/10) × 30 ms = 300 ms</p>
</li>
</ul>
<p>Notice the performance improvement with multithreading, which results in 10 times less time.</p>
<h2 id="heading-when-one-thread-finishes-early-but-other-threads-are-still-working">When One Thread Finishes Early but Other Threads Are Still Working</h2>
<p>In a real-world multithreaded system, it’s very common for one thread to complete its work earlier than the others. This situation has an official name:</p>
<p><strong>👉 It’s called Load Imbalance.</strong></p>
<p>This happens when different threads do not get an equal amount of work, causing:</p>
<ul>
<li><p>Some threads to finish early.</p>
</li>
<li><p>Some threads to keep working.</p>
</li>
<li><p>CPU cores to remain partially idle.</p>
</li>
<li><p>Total execution time to be determined by the slowest thread.</p>
</li>
</ul>
<p>But what happens next depends on the threading model your program uses. Here’s how it plays out in practice.</p>
<ol>
<li><p><strong>Static Assignment → Idle Threads (Bad Scenario)</strong></p>
<p> In simple or naive multithreading designs, each thread gets a predefined chunk of work.</p>
<p> <strong>Example:</strong></p>
<ul>
<li><p>Thread 1 → Files 1-25</p>
</li>
<li><p>Thread 2 → Files 26-50</p>
</li>
<li><p>Thread 3 → Files 51-75</p>
</li>
<li><p>Thread 4 → Files 76-100</p>
</li>
</ul>
</li>
</ol>
<p>    If Thread 1 finishes early, it has nothing else to do.</p>
<ul>
<li><p>This is called Thread Idle Time</p>
</li>
<li><p>The root cause is Load Imbalance</p>
</li>
<li><p>The CPU core remains underutilized</p>
</li>
<li><p>The program finishes when the slowest thread completes.</p>
</li>
</ul>
<p>    This is why static splitting is rarely used today for large workloads.</p>
<ol start="2">
<li><p><strong>Dynamic Task Queue → Automatic Load Balancing (Good Scenario)</strong></p>
<p> Modern thread pools do not pre-assign tasks. Instead, all tasks are placed in a shared global queue.</p>
<p> <strong>Each thread:</strong></p>
<ul>
<li><p>Takes a task</p>
</li>
<li><p>Executes it</p>
</li>
<li><p>Returns for more</p>
</li>
</ul>
</li>
</ol>
<p>    <strong>👉 It simply grabs the next available task.</strong></p>
<p>    This technique is called <strong>Dynamic Load Balancing</strong>, <strong>Work Queue Model</strong></p>
<p>    <strong>Result:</strong></p>
<ul>
<li><p>No idle threads</p>
</li>
<li><p>All threads stay active</p>
</li>
<li><p>Tasks finish at roughly the same time</p>
</li>
<li><p>Total execution time is much shorter</p>
</li>
</ul>
<ol start="3">
<li><p><strong>Work-Stealing Scheduler → Smart Redistribution (Best Scenario)</strong></p>
<p> Go, Rust, Java ForkJoinPool, and modern runtimes use an even more advanced strategy:</p>
<p> <strong>Work Stealing.</strong></p>
<p> Each thread has its own deque of tasks.</p>
<p> <strong>If a thread finishes early:</strong></p>
<p> <strong>👉 It “steals” remaining tasks from other threads.</strong></p>
<p> This eliminates load imbalance almost entirely.</p>
<p> Benefits:</p>
<ul>
<li><p>Highly efficient</p>
</li>
<li><p>Minimizes idle time</p>
</li>
<li><p>Perfect for large, uneven workloads</p>
</li>
<li><p>Powers Go’s goroutines scheduler.</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Concurrency is about handling multiple tasks at once, while parallelism is about executing them simultaneously. Multithreading is ideal for I/O-heavy tasks, whereas multiprocessing is best for CPU-heavy workloads that benefit from true parallel execution.</p>
<p>Modern runtimes use dynamic load balancing and work-stealing to avoid load imbalances, ensuring that threads don’t sit idle when others are still working. Choosing between threads, processes, or asynchronous patterns depends entirely on your workload, not on which technique is faster.</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Error Handling in Go - The Art of Simplicity and Clarity]]></title><description><![CDATA[Error handling is one of the most defining design choices in Go. While other languages use exceptions, try/catch, or even silent failures, Go does something refreshingly different: it treats errors as regular values.
In this blog, we’ll dive deep int...]]></description><link>https://blog.rohitlokhande.in/error-handling-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/error-handling-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[error handling]]></category><category><![CDATA[error-handling-in-go]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Tue, 11 Nov 2025 15:57:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762879581487/95c48f09-e9c6-4689-a588-b1dc99c9fb84.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Error handling is one of the most defining design choices in Go. While other languages use exceptions, try/catch, or even silent failures, Go does something refreshingly different: it treats <code>errors as regular values.</code></p>
<p>In this blog, we’ll dive deep into how Go handles errors, why this approach is brilliant, and how to master it in your code.</p>
<h2 id="heading-understanding-the-error-type">Understanding the error type</h2>
<p>In Go, error is just an interface:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> error <span class="hljs-keyword">interface</span> {
    Error() <span class="hljs-keyword">string</span>
}
</code></pre>
<p>That’s it.<br />Any type that has an Error() method returning a string qualifies as an error.<br />This simplicity gives developers complete control over how errors are represented and handled.</p>
<h2 id="heading-returning-errors-from-functions">Returning Errors from Functions</h2>
<p>In Go, functions often return two values: one is the expected result, and the other is an error.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
   <span class="hljs-string">"errors"</span>
   <span class="hljs-string">"fmt"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">divide</span><span class="hljs-params">(a,b <span class="hljs-keyword">float64</span>)</span> <span class="hljs-params">(<span class="hljs-keyword">float64</span>, error)</span></span> {
    <span class="hljs-keyword">if</span> b == <span class="hljs-number">0</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>, errors.New(<span class="hljs-string">"cannot divide by zero"</span>)
    }
    <span class="hljs-keyword">return</span> a / b, <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    result, err := divide(<span class="hljs-number">10</span>,<span class="hljs-number">0</span>)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error:"</span>, err)
        <span class="hljs-keyword">return</span>
    }
    fmt.Println(<span class="hljs-string">"Result:"</span>,result)
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-go">Error: cannot divide by zero
</code></pre>
<blockquote>
<p>This pattern → <code>value, err := function()</code> is everywhere in Go.</p>
</blockquote>
<p>It may seem verbose at first, but it makes error handling predictable and explicit. You always know which operations can fail and how they’re handled.</p>
<h2 id="heading-creating-custom-error-types">Creating Custom Error Types</h2>
<p>Go allows you to define custom errors for more meaningful messages.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DivideError <span class="hljs-keyword">struct</span> {
    Dividend <span class="hljs-keyword">float64</span>
    Divisor <span class="hljs-keyword">float64</span>
    Message <span class="hljs-keyword">string</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e *DivideError)</span> <span class="hljs-title">Error</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"cannot divide %.2f by %.2f: %s"</span>, e.Dividend, e.Divisor, e.Message)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">divide</span><span class="hljs-params">(a,b <span class="hljs-keyword">float64</span>)</span> <span class="hljs-params">(<span class="hljs-keyword">float64</span>, error)</span></span> {
    <span class="hljs-keyword">if</span> b == <span class="hljs-number">0</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>, &amp;DivideError{a,b,<span class="hljs-string">"division by zero"</span>}
    }
    <span class="hljs-keyword">return</span> a / b, <span class="hljs-literal">nil</span>
}
</code></pre>
<h2 id="heading-wrapping-and-unwrapping-errors">Wrapping and Unwrapping Errors</h2>
<h3 id="heading-the-problem-wrapping-solves">The problem wrapping solves</h3>
<p>When an error occurs deep in your call stack, you usually want to:</p>
<ul>
<li><p>Return the original error so callers can detect it, and</p>
</li>
<li><p>Add context so logs/debugging are helpful</p>
</li>
</ul>
<p>This lets you do both: attach context while preserving the original error for detection.</p>
<h3 id="heading-how-to-wrap-an-error">How to wrap an error</h3>
<p>Use <code>fmt.Errorf</code> with the <code>%w</code> verb:</p>
<pre><code class="lang-go"><span class="hljs-keyword">import</span> (
    <span class="hljs-string">"errors"</span>
    <span class="hljs-string">"fmt"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">readConfig</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">return</span> errors.New(<span class="hljs-string">"file not found"</span>)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">load</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">if</span> err := readConfig(); err != <span class="hljs-literal">nil</span> {
        <span class="hljs-keyword">return</span> fmt.Errorf(<span class="hljs-string">"load failed: %w"</span>, err) <span class="hljs-comment">// wrap</span>
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}
</code></pre>
<p><code>%w</code> creates a wrapped error that keeps the original error inside.</p>
<blockquote>
<p>Important: use %w (not %v) when you want the error to be unwrappable.</p>
</blockquote>
<h3 id="heading-how-to-check-wrapped-errors">How to check wrapped errors</h3>
<p>Use <code>errors.Is</code> to compare against the original error (or sentinel)</p>
<pre><code class="lang-go">err := load()
<span class="hljs-keyword">if</span> errors.Is(err, errors.New(<span class="hljs-string">"file not found"</span>)) { <span class="hljs-comment">// this won't match sentinel created here</span>
    <span class="hljs-comment">// BAD: errors.New returns a new value; comparison fails.</span>
}
</code></pre>
<p>A better pattern is to have a package-level sentinel or typed error:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> ErrNotFound = errors.New(<span class="hljs-string">"file not found"</span>)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">readConfig</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">return</span> ErrNotFound
}

<span class="hljs-comment">// later</span>
<span class="hljs-keyword">if</span> errors.Is(err, ErrNotFound) {
    fmt.Println(<span class="hljs-string">"config missing"</span>)
}
</code></pre>
<p><code>errors.Is(err, target)</code> walks the chain of wrapped errors and returns true if any match.</p>
<h3 id="heading-typed-errors-and-errorsas">Typed errors and <code>errors.As</code></h3>
<p>If you have richer error types (structs), use <code>errors.As</code> to extract them.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> MyErr <span class="hljs-keyword">struct</span> {
    Code <span class="hljs-keyword">int</span>
    Msg <span class="hljs-keyword">string</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">do</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">return</span> &amp;MyErr{Code: <span class="hljs-number">42</span>, Msg: <span class="hljs-string">"boom"</span>}
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e *MyErr)</span> <span class="hljs-title">Error</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"Code %d: %s"</span>, e.Code, e.Msg)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    err := do()
    <span class="hljs-keyword">var</span> me *MyErr
    <span class="hljs-keyword">if</span> errors.As(err, &amp;me) {
        fmt.Println(<span class="hljs-string">"Got MyErr with code:"</span>,me.Code)
    }
}
</code></pre>
<p><code>errors.As</code> finds the first error in the chain that can be assigned to the provided type.</p>
<h3 id="heading-how-errorsas-uses-the-pointer"><strong>How</strong> <code>errors.As()</code> <strong>uses the pointer</strong></h3>
<p><code>errors.As()</code> works by attempting a type assertion internally.</p>
<ul>
<li><p>It checks the type of the incoming error (<code>err</code>).</p>
</li>
<li><p>If the types match (i.e., <code>err</code> is a <code>*MyErr</code>), <code>errors.As()</code> needs a way to write the actual error data into a variable you control.</p>
</li>
<li><p>By passing <code>&amp;me</code> (which is a pointer to your pointer variable <code>me</code>), you are giving <code>errors.As()</code> the memory address where it should store the found error value.</p>
</li>
</ul>
<h3 id="heading-unwrapping-manually">Unwrapping manually</h3>
<p>You can get the wrapped error directly.</p>
<pre><code class="lang-go">w := fmt.Error(<span class="hljs-string">"top %w"</span>, ErrorNotFound)
fmt.Println(errors.Unwrap(w)) <span class="hljs-comment">// prints ErrNotFound</span>
</code></pre>
<p>Now let's understand this wrapping and checking process with a complete example.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"errors"</span>
    <span class="hljs-string">"fmt"</span>
)
<span class="hljs-keyword">var</span> ErrorNotFound = errors.New(<span class="hljs-string">"not found"</span>)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">readConfig</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">return</span> ErrNotFound
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">load</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">if</span> err := readConfig(); err != <span class="hljs-literal">nil</span> {
        <span class="hljs-keyword">return</span> fmt.Errorf(<span class="hljs-string">"load config: %w"</span>, err)
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">if</span> err := load(); err != <span class="hljs-literal">nil</span> {
        <span class="hljs-keyword">return</span> fmt.Errorf(<span class="hljs-string">"run failed: %w"</span>, err)
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">if</span> err := run(); err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"error:"</span>, err) <span class="hljs-comment">// prints full wrapped message</span>
        <span class="hljs-keyword">if</span> errors.Is(err,ErrNotFound) {
            fmt.Println(<span class="hljs-string">"detect not found"</span>)
        }
    }
}
</code></pre>
<p>Expected output:</p>
<pre><code class="lang-bash">error: run failed: load config: not found
detect not found
</code></pre>
<p>You get the full human-readable context plus the ability to detect the original error programmatically.</p>
<h2 id="heading-panic-amp-recover">Panic &amp; Recover</h2>
<h3 id="heading-what-is-panic">What is Panic?</h3>
<p>Panic stops normal execution and begins to unwind the stack, running deferred functions as it goes. It’s intended for programmer errors or truly unrecoverable conditions, not for normal error handling.</p>
<p>Example triggers:</p>
<ul>
<li><p>index out of range</p>
</li>
<li><p>nil pointer deref</p>
</li>
<li><p>explicit panic(“bad state“)</p>
</li>
</ul>
<h3 id="heading-recover-how-to-catch-a-panic">Recover: how to catch a panic</h3>
<p><code>recover()</code> can regain control only if it is called inside a deferred function on the same goroutine where the panic occurred.</p>
<p>If recover() returns non-nil, the panic is stopped, and normal execution resumes after that deferred function returns.</p>
<blockquote>
<p>Important: recover() does not work across goroutines.</p>
</blockquote>
<h3 id="heading-basic-pattern-graceful-recovery-at-the-boundary">Basic pattern: graceful recovery at the boundary</h3>
<p>Common usage: put a <strong>defer + recover()</strong> near the top-level of goroutine (HTTP handler, worker, CLI entry point) to prevent a panic from crashing the whole process and to transform it into an error or log.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">safeRun</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">defer</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">if</span> r := <span class="hljs-built_in">recover</span>(); r != <span class="hljs-literal">nil</span> {
            fmt.Println(<span class="hljs-string">"recovered from panic:"</span>,r)
            <span class="hljs-comment">// optional: log stack trace: debug.PrintStack()</span>
        }
    }()

    <span class="hljs-comment">// Code that might panic</span>
    mustDo()
    fmt.Println(<span class="hljs-string">"safeRun completed"</span>)
}
</code></pre>
<p>If <code>mustDo()</code> panics, the deferred function sees it and recovers. The program continues, and you can convert the panic to a meaningful error.</p>
<p>Now that we understand what panic and recover are and how to use them, the next question is when does recover() return nil and when does it not? Let's explore that.</p>
<h3 id="heading-when-recover-returns-non-nil">When recover() returns non-nil</h3>
<p>It returns non-nil only when:</p>
<ul>
<li><p>a panic is currently in progress in the same goroutine,</p>
</li>
<li><p>and you call recover() inside a deferred function.</p>
</li>
</ul>
<p>That’s the only time recover actually “catches” a panic.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">defer</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">if</span> r := <span class="hljs-built_in">recover</span>(); r != <span class="hljs-literal">nil</span> {
            fmt.Println(<span class="hljs-string">"Recovered from panic:"</span>,r)
        }
    }()
    fmt.Println(<span class="hljs-string">"Before panic"</span>)
    <span class="hljs-built_in">panic</span>(<span class="hljs-string">"Something went wrong!"</span>)
    fmt.Println(<span class="hljs-string">"Before panic"</span>) <span class="hljs-comment">// never runs</span>
}
</code></pre>
<p>Output for above code</p>
<pre><code class="lang-bash">Before panic
Recovered from panic: Something went wrong!
</code></pre>
<p>Here, recover() returns "Something went wrong!" (the panic value), which is non-nil.</p>
<h3 id="heading-when-recover-returns-nil">When recover() returns nil</h3>
<p>There are three main cases when recover() returns nil</p>
<ol>
<li><p><strong>No panic is happening</strong></p>
<p> If you just call recover() normally—not during a panic—it always returns nil.</p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
     fmt.Println(<span class="hljs-built_in">recover</span>()) <span class="hljs-comment">// nil - no panic is happening</span>
 }
</code></pre>
</li>
<li><p><strong>You call recover() outside a deferred function</strong></p>
<p> Recover only works when called from within a defer.</p>
<p> If you call it outside, even if a panic happened earlier, it won’t stop the panic.</p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
     <span class="hljs-built_in">panic</span>(<span class="hljs-string">"Boom!"</span>)
     fmt.Println(<span class="hljs-built_in">recover</span>()) <span class="hljs-comment">// never runs</span>
 }
</code></pre>
<p> This never runs—the program crashes because recover() must be inside a deferred function to intercept the panic.</p>
</li>
<li><p><strong>Recover is in a defer but not executed during that panic</strong></p>
</li>
</ol>
<p>If your function has multiple defers, only those active during the panic’s unwinding can recover it.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">demo</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">defer</span> fmt.Println(<span class="hljs-string">"First defer"</span>) <span class="hljs-comment">// this runs</span>
    <span class="hljs-keyword">defer</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        fmt.Println(<span class="hljs-string">"Second defer - no panic now"</span>)
        fmt.Println(<span class="hljs-string">"Recover here:"</span>, <span class="hljs-built_in">recover</span>()) <span class="hljs-comment">// returns nil</span>
    }()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    demo()
}
</code></pre>
<pre><code class="lang-bash">Second defer - no panic now
Recover here: &lt;nil&gt;
First defer
</code></pre>
<p>There’s no active panic when the defer runs, so recover() returns nil.</p>
<blockquote>
<p>The last declared defer function will execute first.</p>
</blockquote>
<h3 id="heading-easy-way-to-remember">Easy way to remember</h3>
<blockquote>
<p>recover() works only once, and only when it’s called inside a deferred function during the panic unwind.</p>
</blockquote>
<p>If you call it:</p>
<ul>
<li><p>too early (no panic yet) → nil</p>
</li>
<li><p>too late (panic already recovered or finished) → nil</p>
</li>
<li><p>outside defer → nil</p>
</li>
</ul>
<h2 id="heading-when-to-use-panic-recover">When to use panic + recover</h2>
<ul>
<li><p>Use panic for programmer mistakes or invariant violations, e.g., impossible states.</p>
</li>
<li><p>Use panic for unrecoverable system-level errors if the right thing is to crash, then rely on supervisors like systems or Kubernetes to restart.</p>
</li>
<li><p>Use recover near goroutine boundaries to prevent a single goroutine panic from killing the whole process and convert panic into an error if appropriate.</p>
</li>
<li><p>Don’t use panic for ordinary error handling—<strong>use error returns</strong>.</p>
</li>
</ul>
<h2 id="heading-real-world-use-cases-for-panic-recover">Real-World Use Cases for panic + recover</h2>
<ol>
<li><p><strong>Graceful recovery in long-running servers like web servers</strong></p>
<p> <strong>Scenario:</strong></p>
<p> In production systems, e.g., web APIs and background workers, a single handler might panic because of a bug, nil pointer, or invalid operation.<br /> If we let that panic crash the entire process, it would take down the whole server.</p>
<p> So, we use recover in middleware to catch panics per request, log them, and keep the server alive.</p>
</li>
<li><p><strong>Handling unexpected panics in goroutines</strong></p>
<p> When you launch multiple goroutines, a panic in one goroutine doesn't automatically crash others, but if it happens in the main goroutine, it kills the program.</p>
</li>
<li><p><strong>In frameworks and libraries</strong></p>
<p> When you build reusable libraries or frameworks like a task runner, job scheduler, or web framework, you often want to protect user-defined callbacks.</p>
<p> If user code panics, your library should recover and report it as an error instead of dying.</p>
</li>
</ol>
<h2 id="heading-gos-error-handling-philosophy">Go’s Error Handling Philosophy</h2>
<p>Go’s designers had one goal in mind — clarity and simplicity.<br />By making errors explicit, they eliminated the hidden complexity that comes with exception handling systems.</p>
<p>You’ll often see this idiom:</p>
<pre><code class="lang-go"><span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
    <span class="hljs-keyword">return</span> err
}
</code></pre>
<p>At first, it may seem repetitive, but this repetition ensures predictability.<br />No hidden stack traces. No silent skips. Just clean, explicit logic.</p>
<h2 id="heading-go-vs-other-languages">Go vs Other Languages</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Go</td><td>Java/Python/C++</td></tr>
</thead>
<tbody>
<tr>
<td>Mechanism</td><td>Return errors explicitly</td><td>Execptions</td></tr>
<tr>
<td>Error type</td><td>error interface</td><td>Execption classes</td></tr>
<tr>
<td>Control flow</td><td>Normal execution</td><td>Try/Catch blocks</td></tr>
<tr>
<td>Performance</td><td>Fast, no stack unwinding</td><td>Slower due to exception overhead</td></tr>
<tr>
<td>Debhugging</td><td>Simple, explicit</td><td>Complex trace handling</td></tr>
</tbody>
</table>
</div><p>Before wrapping up this blog, let's compare this with an example in JavaScript and Go to understand the differences.</p>
<p>Let’s take the scenario of fetching user data and saving it to a database.</p>
<p>We’ll build a small imaginary flow:</p>
<ol>
<li><p>Fetch user data from an API</p>
</li>
<li><p>Validate it</p>
</li>
<li><p>Save it to a database</p>
</li>
</ol>
<p>We’ll see how this looks in JavaScript (with try/catch) and Go (with explicit error handling).</p>
<h3 id="heading-javascript-version-with-asyncawait-and-trycatch">Javascript Version (with async/await and try/catch)</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUser</span>(<span class="hljs-params">id</span>) </span>{
  <span class="hljs-keyword">if</span> (!id) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Invalid user ID"</span>);
  <span class="hljs-comment">// simulate API fetch</span>
  <span class="hljs-keyword">return</span> { id, <span class="hljs-attr">name</span>: <span class="hljs-string">"Alice"</span> };
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateUser</span>(<span class="hljs-params">user</span>) </span>{
  <span class="hljs-keyword">if</span> (!user.name) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"User name missing"</span>);
  <span class="hljs-keyword">return</span> user;
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveUserToDB</span>(<span class="hljs-params">user</span>) </span>{
  <span class="hljs-keyword">if</span> (user.name === <span class="hljs-string">"Alice"</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Duplicate user"</span>);
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchUser(<span class="hljs-number">1</span>);
    <span class="hljs-keyword">const</span> validUser = <span class="hljs-keyword">await</span> validateUser(user);
    <span class="hljs-keyword">await</span> saveUserToDB(validUser);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"User saved successfully!"</span>);
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Something went wrong:"</span>, err.message);
  }
}

main();
</code></pre>
<p>What’s happening here:</p>
<ul>
<li><p>Errors are thrown and caught in a try/catch block.</p>
</li>
<li><p>If any function fails, JavaScript unwinds the stack until a catch is found.</p>
</li>
<li><p>It looks clean, but:</p>
<ul>
<li><p>The error origin (which function failed) may not always be clear.</p>
</li>
<li><p>If you forget one await or don’t wrap async code properly, the error might bubble silently.</p>
</li>
<li><p>Handling specific errors like network errors vs. validation errors requires manual parsing of <code>err.message</code>.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-go-version-explicit-error-handling">Go Version (explicit error handling)</h3>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"errors"</span>
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
    ID   <span class="hljs-keyword">int</span>
    Name <span class="hljs-keyword">string</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetchUser</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>)</span> <span class="hljs-params">(User, error)</span></span> {
    <span class="hljs-keyword">if</span> id == <span class="hljs-number">0</span> {
        <span class="hljs-keyword">return</span> User{}, errors.New(<span class="hljs-string">"invalid user ID"</span>)
    }
    <span class="hljs-keyword">return</span> User{ID: id, Name: <span class="hljs-string">"Alice"</span>}, <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">validateUser</span><span class="hljs-params">(user User)</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">if</span> user.Name == <span class="hljs-string">""</span> {
        <span class="hljs-keyword">return</span> errors.New(<span class="hljs-string">"user name missing"</span>)
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">saveUserToDB</span><span class="hljs-params">(user User)</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">if</span> user.Name == <span class="hljs-string">"Alice"</span> {
        <span class="hljs-keyword">return</span> errors.New(<span class="hljs-string">"duplicate user"</span>)
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    user, err := fetchUser(<span class="hljs-number">1</span>)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error fetching user:"</span>, err)
        <span class="hljs-keyword">return</span>
    }

    <span class="hljs-keyword">if</span> err := validateUser(user); err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Validation error:"</span>, err)
        <span class="hljs-keyword">return</span>
    }

    <span class="hljs-keyword">if</span> err := saveUserToDB(user); err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Database error:"</span>, err)
        <span class="hljs-keyword">return</span>
    }

    fmt.Println(<span class="hljs-string">"User saved successfully!"</span>)
}
</code></pre>
<p>What's happening here:</p>
<ul>
<li><p>Each function returns an error value—no throwing, no hidden jumps.</p>
</li>
<li><p>You handle the error right where it happens.</p>
</li>
<li><p>You can wrap or categorize errors easily using <code>fmt.Errorf</code>, <code>errors.Is</code>, or <code>errors.As</code>.</p>
</li>
<li><p>The flow is fully predictable—no stack unwinding, no implicit control flow.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Error handling in Go isn’t just about catching problems; it’s about designing programs that expect and gracefully manage them.</p>
<p>By making errors explicit:</p>
<ul>
<li><p>Your code becomes more predictable</p>
</li>
<li><p>Your debugging becomes simpler</p>
</li>
<li><p>Your software becomes more robust</p>
</li>
</ul>
<p>So the next time you write</p>
<pre><code class="lang-go"><span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
    <span class="hljs-keyword">return</span> err
}
</code></pre>
<p>remember — this isn’t boilerplate.<br />It’s Go’s way of saying</p>
<blockquote>
<p>Handle your problems, don’t hide them.</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Understanding Generics in Go: The Power of Type Parameters]]></title><description><![CDATA[When Go was first introduced, one of the most debated missing features was Generics, the ability to write code that works for any data type without sacrificing type safety.With Go 1.18, that changed forever.
Generics make Go code more reusable, less ...]]></description><link>https://blog.rohitlokhande.in/generics-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/generics-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[Golang developer]]></category><category><![CDATA[generics]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Sun, 09 Nov 2025 08:30:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762675732661/dd0cc5cc-fd6d-47ba-ad8f-599899ad0202.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When Go was first introduced, one of the most debated missing features was Generics, the ability to write code that works for any data type without sacrificing type safety.<br />With <strong>Go 1.18</strong>, that changed forever.</p>
<p>Generics make Go code more reusable, less repetitive, and safer — all without losing the language’s hallmark simplicity.</p>
<h2 id="heading-why-are-generics-needed">Why are Generics needed?</h2>
<p>Imagine you want to write a function that finds the minimum value in a slice:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">MinInt</span><span class="hljs-params">(a, b <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    <span class="hljs-keyword">if</span> a &lt; b {
       <span class="hljs-keyword">return</span> a
    }
    <span class="hljs-keyword">return</span> b
}
</code></pre>
<p>If you later need the same function for <code>float64</code>, you’d have to write another one.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">MinFloat</span><span class="hljs-params">(a,b <span class="hljs-keyword">float64</span>)</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">if</span> a &lt; b {
        <span class="hljs-keyword">return</span> a
    } 
    <span class="hljs-keyword">return</span> b
}
</code></pre>
<p>This is code duplication with the same logic, just different types.</p>
<p>Generics solve this problem.</p>
<h2 id="heading-what-are-generics">What Are Generics?</h2>
<p>Generics allow you to write functions, structs, and methods that can work with any type.<br />They do this using <strong>type parameters</strong>, which are placeholders for types that you define when using the function or struct.</p>
<p>Think of type parameters like "boxes" that hold different types, but still guarantee what kind of things they can hold.</p>
<p>Now let's make the above code example generic so we don't need to create two functions to find the minimum for int and float data types.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Min</span>[<span class="hljs-title">T</span> <span class="hljs-title">any</span>]<span class="hljs-params">(a,b T)</span> <span class="hljs-title">T</span></span> {
    <span class="hljs-keyword">if</span> a &lt; b {
        <span class="hljs-keyword">return</span> a
    }
    <span class="hljs-keyword">return</span> b
}
</code></pre>
<p>Let’s break it down and understand each keyword:</p>
<ul>
<li><p>T → It is a type parameter, just like a variable name but for types.</p>
</li>
<li><p>[T any] → Declares that this function uses a type parameter T, which can be any type.</p>
</li>
<li><p>a, b T → Function arguments that must both be of type T.</p>
</li>
<li><p>The function returns a value of type T.</p>
</li>
</ul>
<p>We have made the function generic for all data types, but there’s a problem.<br />Not all types can use the <code>&lt;</code> operator (like structs or slices), so it needs some constraints.</p>
<h2 id="heading-type-constraints">Type Constraints</h2>
<p>A constraint defines what operations are allowed on a type parameter.</p>
<p>Built-in constraints</p>
<ul>
<li><p>any → allows any type</p>
</li>
<li><p>comparable → allows types that can use == and !=</p>
</li>
<li><p>Custom constraints can be created using interfaces</p>
</li>
</ul>
<h3 id="heading-built-in-constraints-in-go">Built-in Constraints in Go</h3>
<ol>
<li><p><strong>any</strong></p>
<p> Represents all possible types.<br /> It’s equivalent to an empty interface (interface{}) in older Go versions.</p>
<p> Example:</p>
</li>
</ol>
<ol>
<li><pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">PrintValue</span>[<span class="hljs-title">T</span> <span class="hljs-title">any</span>] <span class="hljs-params">(v T)</span></span> {
     fmt.Println(v)
 }
</code></pre>
<p> Here, T can be any type — string, int, struct etc</p>
</li>
<li><p><strong>Comparable</strong></p>
<p> Represents all types that can be compared using == and !=.</p>
<p> That includes primitive types like int, string, bool, and even structs if all their fields are comparable.</p>
<p> Example</p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">AreEauqal</span>[<span class="hljs-title">T</span> <span class="hljs-title">comparable</span>]<span class="hljs-params">(a,b T)</span> <span class="hljs-title">bool</span></span> {
     <span class="hljs-keyword">return</span> a == b
 }
</code></pre>
<p> Usage:</p>
<pre><code class="lang-go"> fmt.Println(AreEqual(<span class="hljs-number">10</span>,<span class="hljs-number">10</span>)) <span class="hljs-comment">// true</span>
 fmt.Println(AreEqual(<span class="hljs-string">"go"</span>,<span class="hljs-string">"rust"</span>)) <span class="hljs-comment">// false</span>
</code></pre>
<p> This prevents you from accidentally using non-comparable types like slices or maps.</p>
</li>
<li><p><strong>Custom Constraints</strong></p>
<p> You can create your own constraints using interfaces and type unions.</p>
</li>
</ol>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Ordered <span class="hljs-keyword">interface</span> {
    ~<span class="hljs-keyword">int</span> | ~<span class="hljs-keyword">float64</span> | ~<span class="hljs-keyword">string</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Min</span>[<span class="hljs-title">T</span> <span class="hljs-title">Ordered</span>]<span class="hljs-params">(a, b T)</span> <span class="hljs-title">T</span></span> {
    <span class="hljs-keyword">if</span> a &lt; b {
        <span class="hljs-keyword">return</span> a
    }
    <span class="hljs-keyword">return</span> b
}
</code></pre>
<p>In the above code, only ordered types (numbers and strings) can use this Min function.</p>
<p>This is type safety + flexibility combined.</p>
<p>Here:</p>
<ul>
<li><p><code>~</code> means “underlying type of”.</p>
</li>
<li><p>The Ordered constraint allows types that are comparable using &lt;.</p>
</li>
</ul>
<p>Let’s dive deep into the <code>~</code> operator and underlying types.</p>
<p>The tilde (~) symbol in Go generics is used to match types that have a specific underlying type, even if they are custom type definitions.</p>
<h3 id="heading-what-is-an-underlying-type">What is an Underlying Type?</h3>
<p>In Go, when you create a custom type, it's based on another existing type—that's its underlying type.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> MyInt <span class="hljs-keyword">int</span>
<span class="hljs-keyword">type</span> Score <span class="hljs-keyword">float64</span>
</code></pre>
<p>Here,</p>
<ul>
<li><p>MyInt has an underlying type of int</p>
</li>
<li><p>Score has an underlying type of float64</p>
</li>
</ul>
<p>So even though MyInt and Score are distinct types, they are built on top of primitive types.</p>
<h3 id="heading-why-matters-in-constraints">Why <code>~</code> Matters in Constraints</h3>
<p>If you don’t use ~, your constraint only accepts exact matches.<br />If you use ~, it also accepts types derived from that underlying type.</p>
<p><strong>Without</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Ordered <span class="hljs-keyword">interface</span> {
    <span class="hljs-keyword">int</span> | <span class="hljs-keyword">float64</span>
}
</code></pre>
<p>Works for int, float64, but fails for MyInt (even though it’s based on int).</p>
<p>With</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Ordered <span class="hljs-keyword">interface</span> {
    ~<span class="hljs-keyword">int</span> | ~<span class="hljs-keyword">float64</span>
}
</code></pre>
<ul>
<li><p>Works for int</p>
</li>
<li><p>Works for MyInt</p>
</li>
<li><p>Works for float64</p>
</li>
<li><p>Works for any type whose underlying type is int or float64</p>
</li>
</ul>
<h2 id="heading-generic-structs">Generic Structs</h2>
<p>You can also define structs with type parameters.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Pair[T, U any] <span class="hljs-keyword">struct</span> {
    First T
    Second U
}
</code></pre>
<p>Usage:</p>
<pre><code class="lang-go">p := Pair[<span class="hljs-keyword">string</span>, <span class="hljs-keyword">int</span>]{First: <span class="hljs-string">"Age"</span>, Second: <span class="hljs-number">25</span>}
fmt.Println(p.First, p.Second)
</code></pre>
<h2 id="heading-generic-methods">Generic Methods</h2>
<p>You can also attach methods to generic types.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Stack[T any] <span class="hljs-keyword">struct</span> {
    items []T
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(s *Stack[T])</span> <span class="hljs-title">Push</span><span class="hljs-params">(item T)</span></span> {
    s.items = <span class="hljs-built_in">append</span>(s.items, item)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(s *Stack[T])</span> <span class="hljs-title">Pop</span><span class="hljs-params">()</span> <span class="hljs-title">T</span></span> {
    n := <span class="hljs-built_in">len</span>(s.items)
    item := s.items[n<span class="hljs-number">-1</span>]
    s.items = s.items[:n<span class="hljs-number">-1</span>]
    <span class="hljs-keyword">return</span> item
}
</code></pre>
<p>Usage:</p>
<pre><code class="lang-go">s := Stack[<span class="hljs-keyword">int</span>]{}
s.push(<span class="hljs-number">10</span>)
s.push(<span class="hljs-number">20</span>)
fmt.Println(s.Pop()) <span class="hljs-comment">// 20</span>
</code></pre>
<h2 id="heading-type-inference">Type Inference</h2>
<p>You don’t always have to specify the type manually. Go’s compiler can infer the type from your arguments.</p>
<pre><code class="lang-go">PrintSlice([]<span class="hljs-keyword">string</span>{<span class="hljs-string">"Go"</span>,<span class="hljs-string">"Rust"</span>,<span class="hljs-string">"Python"</span>,<span class="hljs-string">"JS"</span>})
</code></pre>
<p>If the function is defined as:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">PrintSlice</span>[<span class="hljs-title">T</span> <span class="hljs-title">any</span>]<span class="hljs-params">(s[]T)</span></span> {
    <span class="hljs-keyword">for</span> _,v := <span class="hljs-keyword">range</span> s {
        fmt.Println(v)
    }
}
</code></pre>
<p>Go automatically understands that T is a string.</p>
<h2 id="heading-real-world-use-cases">Real-World Use Cases</h2>
<ul>
<li><p>Utility functions (like Min, Max, contains)</p>
</li>
<li><p>Data structures (Stack, Queue, Tree)</p>
</li>
<li><p>Generic database models or repositories</p>
</li>
<li><p>Writing reusable libraries</p>
</li>
</ul>
<h2 id="heading-performance-and-limitations">Performance and Limitations</h2>
<p><strong>Advantages:</strong></p>
<ul>
<li><p>Compile-time type safety</p>
</li>
<li><p>No need for reflection or type assertions</p>
</li>
<li><p>Less code duplication</p>
</li>
<li><p>Cleaner, reusable APIs</p>
</li>
</ul>
<p><strong>Limitations:</strong></p>
<ul>
<li><p>Slightly more complex syntax</p>
</li>
<li><p>May increase compile time for very large codebases</p>
</li>
<li><p>Not ideal for every use case — sometimes interfaces are simpler</p>
</li>
</ul>
<h2 id="heading-analogy-generics-as-blueprints">Analogy: Generics as Blueprints</h2>
<p>Think of generics as a blueprint for a tool. You design one hammer template, and depending on the type (wood, metal, rubber), Go builds a hammer specialized for that material at compile time.</p>
<p>There's no need to make a separate hammer for each. Just one perfect template works.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Generics bring clarity, reusability, and type safety to Go. They eliminate repetitive code and make libraries more elegant.</p>
<p>If you’ve ever wished you could “write once, use for all types,” then <strong>Generics are the answer.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Unlocking the Power of Structs and Interfaces in Go for Data Structuring]]></title><description><![CDATA[When learning Go, one thing becomes clear early on: Go doesn’t follow traditional Object-Oriented Programming (OOP) patterns like classes and inheritance.Instead, it gives us two powerful tools: Structs and Interfaces.
These two concepts are at the h...]]></description><link>https://blog.rohitlokhande.in/structs-and-interfaces-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/structs-and-interfaces-in-go</guid><category><![CDATA[struct-interface in go]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Go]]></category><category><![CDATA[structs in Go]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Sat, 08 Nov 2025 18:24:31 GMT</pubDate><content:encoded><![CDATA[<p>When learning Go, one thing becomes clear early on: Go doesn’t follow traditional Object-Oriented Programming (OOP) patterns like classes and inheritance.<br />Instead, it gives us two powerful tools: Structs and Interfaces.</p>
<p>These two concepts are at the heart of Go’s design philosophy — <strong>composition over inheritance</strong>.<br />Let’s break them down and see how they work together to build clean and flexible Go programs.</p>
<h2 id="heading-what-are-structs">What Are Structs?</h2>
<p>A struct in Go is a collection of fields, basically a way to group data together. Think of it as Go’s version of an “object” or “class,” but simpler and without inheritance.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Person <span class="hljs-keyword">struct</span> {
    Name <span class="hljs-keyword">string</span>
    Age <span class="hljs-keyword">int</span>
}
</code></pre>
<p>Now we can create and use a <code>Person</code>:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    p1 := Person{Name: <span class="hljs-string">"Rohit"</span>,Age:<span class="hljs-number">25</span>}
    fmt.Println(p1.Name, p1.Age)
}
</code></pre>
<p>Structs help you define custom data types that represent real-world entities like users, orders, products, and more.</p>
<h2 id="heading-creating-structs-in-different-ways">Creating Structs in Different Ways</h2>
<pre><code class="lang-go"><span class="hljs-comment">// Using var</span>
<span class="hljs-keyword">var</span> p1 Person
p1.Name = <span class="hljs-string">"Rohit"</span>
p1.Age = <span class="hljs-number">25</span>

<span class="hljs-comment">// Using shorthand</span>
p2 := Person{<span class="hljs-string">"Alex"</span>,<span class="hljs-number">30</span>}

<span class="hljs-comment">// Using pointers</span>
p2 := &amp;Person{Name: <span class="hljs-string">"John"</span>, Age: <span class="hljs-number">30</span>}
</code></pre>
<blockquote>
<p>Pointers to structs are often used to avoid copying large structs and to modify their values directly.</p>
</blockquote>
<h2 id="heading-nested-and-anonymous-structs">Nested and Anonymous Structs</h2>
<p>You can also define structs inside structs or even anonymous structs.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Address <span class="hljs-keyword">struct</span> {
    City  <span class="hljs-keyword">string</span>
    State <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">type</span> Employee <span class="hljs-keyword">struct</span> {
    Name    <span class="hljs-keyword">string</span>
    Address Address
}
</code></pre>
<p>And access nested fields like this:</p>
<pre><code class="lang-go">fmt.Println(emp.Address.City)
</code></pre>
<p>Anonymous structs are useful when you need something quick and temporary.</p>
<pre><code class="lang-go">person := <span class="hljs-keyword">struct</span> {
    Name <span class="hljs-keyword">string</span>
    Age  <span class="hljs-keyword">int</span>
}{<span class="hljs-string">"Rohit"</span>, <span class="hljs-number">25</span>}
</code></pre>
<h2 id="heading-methods-on-structs">Methods on Structs</h2>
<p>Go doesn't have "classes," but it allows you to attach methods to structs.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p Person)</span> <span class="hljs-title">Greet</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Hello,"</span>, p.Name)
}
</code></pre>
<h2 id="heading-value-receiver-vs-pointer-receiver">Value Receiver vs Pointer Receiver</h2>
<p>When defining methods, you’ll often see two styles:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p Person)</span> <span class="hljs-title">Greet</span><span class="hljs-params">()</span>        // <span class="hljs-title">value</span> <span class="hljs-title">receiver</span></span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *Person)</span> <span class="hljs-title">HaveBirthday</span><span class="hljs-params">()</span> // <span class="hljs-title">pointer</span> <span class="hljs-title">receiver</span></span>
</code></pre>
<ul>
<li><p>Value receiver: Works on a copy; doesn’t change the original data.</p>
</li>
<li><p>Pointer receiver: Works on the original struct; can modify its data.</p>
</li>
</ul>
<h2 id="heading-what-is-a-method-set">What is a Method Set?</h2>
<p>A method set is simply the collection of methods that belong to a type in Go.<br />It defines which methods can be called on a value or a pointer of that type.</p>
<p>Go differentiates between methods with value receivers and methods with pointer receivers.</p>
<p>Let’s see an example first:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-keyword">type</span> Person <span class="hljs-keyword">struct</span> {
  name <span class="hljs-keyword">string</span>
}

<span class="hljs-comment">// Value receiver</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p Person)</span> <span class="hljs-title">SayHello</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Hello, my name is"</span>, p.name)
}

<span class="hljs-comment">// Pointer receiver</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p *Person)</span> <span class="hljs-title">ChangeName</span><span class="hljs-params">(newName <span class="hljs-keyword">string</span>)</span></span> {
    p.name = newName
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    p := Person{name: <span class="hljs-string">"Rohit"</span>}
    p.SayHello()
    p.ChangeName(<span class="hljs-string">"Raj"</span>) <span class="hljs-comment">// Go automatically take the address here</span>

}
</code></pre>
<h2 id="heading-struct-embedding-also-known-as-composition-over-inheritance">Struct Embedding (also known as Composition over Inheritance)</h2>
<p>Go doesn't have inheritance like OOP languages; instead, it uses embedding.<br />You can "embed" one structure inside another to reuse its fields and methods.</p>
<p>Let's understand this with a code example:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-keyword">type</span> Person <span class="hljs-keyword">struct</span> {
    Name <span class="hljs-keyword">string</span>
    Age <span class="hljs-keyword">int</span>
}

<span class="hljs-keyword">type</span> Employee <span class="hljs-keyword">struct</span> {
    Person <span class="hljs-comment">// embedded struct</span>
    Position <span class="hljs-keyword">string</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    e := Employee{
        Person: Person{Name: <span class="hljs-string">"Rohit"</span>, Age: <span class="hljs-number">25</span>},
        Position: <span class="hljs-string">"Software Engineer"</span>,
    }

    <span class="hljs-comment">// Access Person fields directly</span>
    fmt.Println(e.Name) <span class="hljs-comment">// "Rohit"</span>
    fmt.Println(e.Person.Age) <span class="hljs-comment">// also valid</span>
}
</code></pre>
<h3 id="heading-why-use-embedding">Why use embedding?</h3>
<ul>
<li><p>It's a simple way to combine types.</p>
</li>
<li><p>You achieve an "inheritance-like" behavior without the complexity.</p>
</li>
</ul>
<h2 id="heading-interfaces-defining-behavior-not-data">Interfaces — Defining Behavior, Not Data</h2>
<p>While structs define what something is, interfaces define what something does.</p>
<p>For example</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Greeter <span class="hljs-keyword">interface</span> {
  Greet()
}
</code></pre>
<p>If a struct has a Greet() method, it automatically satisfies the Greeter interface. There's no need for explicit "implements" keywords like in Java or C#.</p>
<p>Example:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Greeter <span class="hljs-keyword">interface</span> {
  Greet()
}
<span class="hljs-keyword">type</span> Dog <span class="hljs-keyword">struct</span>{}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(d Dog)</span> <span class="hljs-title">Greet</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Woof! 🐶"</span>)
}

<span class="hljs-keyword">type</span> Person <span class="hljs-keyword">struct</span> {
    Name <span class="hljs-keyword">string</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p Person)</span> <span class="hljs-title">Greet</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Hi, I’m"</span>, p.Name)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">SayHello</span><span class="hljs-params">(g Greeter)</span></span> {
    g.Greet()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    SayHello(Person{Name: <span class="hljs-string">"Rohit"</span>})
    SayHello(Dog{})
}
</code></pre>
<p>Output</p>
<pre><code class="lang-go">Hi, I’m Rohit
Woof! 🐶
</code></pre>
<p>In this, both Person and Dog satisfy the Greeter interface—no explicit declaration needed.</p>
<h2 id="heading-interface-embedding">Interface Embedding</h2>
<p>Similar to struct embedding, you can also embed interfaces.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Reader <span class="hljs-keyword">interface</span> {
    Read(p []<span class="hljs-keyword">byte</span>) (n <span class="hljs-keyword">int</span>, err error)
}

<span class="hljs-keyword">type</span> Writer <span class="hljs-keyword">interface</span> {
    Write(p []<span class="hljs-keyword">byte</span>) (n <span class="hljs-keyword">int</span>, err error)
}

<span class="hljs-keyword">type</span> ReadWriter interfce {
    Reader
    Writer
}
</code></pre>
<p>This way, ReadWriter automatically includes both the Read() and Write() methods.</p>
<h2 id="heading-nil-interface-vs-nil-concrete-value">Nil Interface vs Nil Concrete Value</h2>
<p>This is one of the trickiest Go interface concepts.</p>
<p>Example:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> err error = <span class="hljs-literal">nil</span>
fmt.Println(err == <span class="hljs-literal">nil</span>) <span class="hljs-comment">// true</span>
</code></pre>
<p>But for below code the output is different</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> p *<span class="hljs-keyword">int</span> = <span class="hljs-literal">nil</span>
<span class="hljs-keyword">var</span> any <span class="hljs-keyword">interface</span>{} = p
fmt.Println(any == <span class="hljs-literal">nil</span>) <span class="hljs-comment">// false</span>
</code></pre>
<p>Why?<br />Because an interface internally holds (type, value).<br />Here any has (type=*int, value=nil) → so it’s not fully nil</p>
<blockquote>
<p>Rule:<br />An interface is nil only if both its type and value are nil.</p>
</blockquote>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Structs and interfaces are fundamental concepts in Go that highlight its unique approach to programming. They may seem simple at first glance, but they offer a powerful way to structure and organize code. By understanding how structs and interfaces function, you can appreciate how Go's design philosophy emphasizes clarity, flexibility, and simplicity in software development.</p>
<p>Structs allow you to define complex data types by grouping together variables, known as fields, under a single name. This makes it easier to manage and manipulate related data. Interfaces, on the other hand, define a set of method signatures that a type must implement, enabling polymorphism. This means you can write functions that operate on different types as long as they implement the same interface, promoting code reusability and flexibility.</p>
<p>Once you become familiar with these concepts, you'll notice how Go encourages you to write clear and maintainable code. The language's simplicity doesn't sacrifice power; instead, it provides a robust foundation for building scalable and efficient applications. Embracing Go's approach to structs and interfaces can lead to more intuitive and effective programming, allowing you to focus on solving problems rather than wrestling with complex language features.</p>
]]></content:encoded></item><item><title><![CDATA[How to Work with Strings, Bytes, Runes, and Characters in Go]]></title><description><![CDATA[When you first start working with text in Go, everything seems simple until you meet emojis, accented characters, and UTF-8 encoding. Then suddenly, len("🙂") doesn't equal 1 anymore.
To truly understand how Go handles text, we need to dive into stri...]]></description><link>https://blog.rohitlokhande.in/how-to-work-with-strings-bytes-runes-and-characters-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/how-to-work-with-strings-bytes-runes-and-characters-in-go</guid><category><![CDATA[golang]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[utf8]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Fri, 07 Nov 2025 19:11:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762540964075/a5ca9043-9fac-4787-b55d-174f89ca1d0c.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you first start working with text in Go, everything seems simple until you meet emojis, accented characters, and UTF-8 encoding. Then suddenly, len("🙂") doesn't equal 1 anymore.</p>
<p>To truly understand how Go handles text, we need to dive into strings, bytes, and runes—three closely connected concepts that define how Go represents and processes data in memory.</p>
<p>Before we dive deep into how strings, bytes, and runes work in Go, we first need to understand the unsung hero that powers them all: <strong>UTF-8</strong>.</p>
<p>Every piece of text you see, whether it’s “Hello“, “नमस्ते“, or “🙂“, is nothing more than numbers stored in memory.<br />But how does the computer know which number means what character?<br />That’s where character encoding comes in.</p>
<h2 id="heading-the-problem-from-letters-to-numbers">The Problem From Letters to Numbers</h2>
<p>In the early days, computers used a very limited language called ASCII, which could only represent 128 characters, mostly English letters, digits, and symbols. That worked fine until people wanted to write in other languages or include emojis.</p>
<p>ASCII couldn’t handle words like “ありがとう“ or “नमस्ते“ and definitely not emojis like “🙂“.</p>
<p>We needed something global—a universal system that could represent every character from every language.</p>
<p>That’s when Unicode came to the rescue.</p>
<h3 id="heading-unicode">Unicode</h3>
<p><strong>Unicode</strong> is like a massive multilingual dictionary. It assigns a unique number called a <strong>code point</strong> to every character on Earth.</p>
<p><strong>Examples:</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Character</td><td>Unicode Code Point</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>U+0041</td><td>Latin Capital A</td></tr>
<tr>
<td>क</td><td>U+0915</td><td>Hindi Ka</td></tr>
<tr>
<td>你</td><td>U+4F60</td><td>Chinese “You”</td></tr>
<tr>
<td>🙂</td><td>U+1F642</td><td>Smiling Face Emoji</td></tr>
</tbody>
</table>
</div><p>Now every character has an identity. But there’s still a problem: we need to store these numbers in memory as bytes (0s and 1s). To achieve this, UTF-8 comes into play.</p>
<h2 id="heading-utf-8-how-go-stores-text">UTF-8 How Go Stores Text</h2>
<p>UTF-8 (Unicode Transformation Format - 8-bit) is a way to store Unicode characters as bytes.<br />It’s a variable-length encoding, meaning</p>
<ul>
<li><p>Some characters take 1 byte (like English letters)</p>
</li>
<li><p>Some take 2, 3, or 4 bytes</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Character</td><td>Unicode</td><td>UTF-8 Bytes</td><td>Bytes Used</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>U+0041</td><td>01000001</td><td>1</td></tr>
<tr>
<td>é</td><td>U+00E9</td><td>11000011 10101001</td><td>2</td></tr>
<tr>
<td>क</td><td>U+0915</td><td>11100000 10100100 10010101</td><td>3</td></tr>
<tr>
<td>🙂</td><td>U+1F642</td><td>11110000 10011111 10011001 10000010</td><td>4</td></tr>
</tbody>
</table>
</div><h3 id="heading-in-short">In Short</h3>
<blockquote>
<p>UTF-8 is the bridge between human language and machine memory, and Go builds that bridge right into its foundation.</p>
</blockquote>
<h2 id="heading-why-utf-8-instead-of-utf-16-or-other">Why UTF-8 instead of UTF-16 or other?</h2>
<ol>
<li><p><strong>Simplicity:</strong></p>
<p> UTF-8 is the most common encoding on the web and in Unix systems, so it fits Go’s design philosophy of simplicity and practicality.</p>
</li>
<li><p><strong>Compatibility:</strong></p>
<p> ASCII characters are the same in UTF-8, making it backward compatible and efficient for English text.</p>
</li>
<li><p><strong>Efficiency:</strong></p>
<p> Most programming identifiers, file names, and JSON data are mostly ASCII — UTF-8 uses 1 byte for them, while UTF-16 would use 2 bytes.</p>
</li>
<li><p><strong>Interoperability:</strong></p>
<p> UTF-8 is the standard encoding for most APIs, web data, and Linux systems, making Go programs more portable.</p>
</li>
</ol>
<h2 id="heading-what-exactly-is-a-string-in-go">What Exactly Is a String in Go?</h2>
<p>In Go, a string is more than just text. It’s a read-only slice of bytes, a sequence of raw data stored in UTF-8 format.</p>
<p>That means:</p>
<ul>
<li><p>A string is immutable (you can’t change it after creation).</p>
</li>
<li><p>It stores bytes, not characters.</p>
</li>
<li><p>It’s UTF-8 encoded, meaning every character can take 1 to 4 bytes.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-go">s := <span class="hljs-string">"Hello"</span>
fmt.Println(s)
fmt.Println(<span class="hljs-built_in">len</span>(s)) <span class="hljs-comment">// 5 bytes</span>
</code></pre>
<p>Here <code>len(s)</code> returns 5 because "Hello" uses one byte per character. It's simple ASCII code. But not all text is that simple.</p>
<h2 id="heading-strings-and-utf-8-encoding">Strings and UTF-8 Encoding</h2>
<p>Go supports UTF-8 natively, meaning it can represent any character from any language, including emojis, but they may take more than one byte.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-go">s := <span class="hljs-string">"A🙂"</span>
fmt.Println(<span class="hljs-built_in">len</span>(s)) <span class="hljs-comment">// 5</span>
</code></pre>
<p>Why 5 bytes?</p>
<ul>
<li><p>“A“ → 1 byte</p>
</li>
<li><p>“🙂“ → 4 bytes (because it’s a Unicode character)</p>
</li>
</ul>
<p>So the total is 5 bytes, not 2 characters.</p>
<blockquote>
<p><code>len(s)</code> gives the number of bytes, not characters. For plain English text, bytes = characters, because ASCII characters use 1 byte each.</p>
</blockquote>
<h2 id="heading-bytes-the-raw-data-layer">Bytes — The Raw Data Layer</h2>
<p>A byte in Go is just an alias for uint8, representing the raw binary data behind every string.</p>
<p>When you convert a string to a byte slice, you’re seeing its internal UTF-8 byte representation.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-go">s := <span class="hljs-string">"Hi"</span>
b := []<span class="hljs-keyword">byte</span>(s)
fmt.Println(b) <span class="hljs-comment">// [72 105]</span>
</code></pre>
<p>Each number here is the ASCII code for the character:</p>
<ul>
<li><p>H → 72</p>
</li>
<li><p>I → 105</p>
</li>
</ul>
<p>Think of bytes as the DNA of your string — the smallest building blocks.</p>
<h2 id="heading-runes-the-character-view">Runes — The Character View</h2>
<p>While bytes represent raw data, runes represent characters specifically, as Unicode code points.</p>
<p><strong>In Go:</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> <span class="hljs-keyword">rune</span> = <span class="hljs-keyword">int32</span>
</code></pre>
<p>So each rune can represent one Unicode character, no matter how many bytes it takes.</p>
<p>Let’s understand with the example below.</p>
<pre><code class="lang-go">s := <span class="hljs-string">"A🙂"</span>
r := []<span class="hljs-keyword">rune</span>(s)
fmt.Println(r) <span class="hljs-comment">// [65 128578]</span>
</code></pre>
<p>Here,</p>
<ul>
<li><p>A → Unicode 65</p>
</li>
<li><p>🙂 → Unicode 128578</p>
</li>
</ul>
<p>And if we get bytes from the same string, we get the output below.</p>
<pre><code class="lang-go">s := <span class="hljs-string">"A🙂"</span>
b := []<span class="hljs-keyword">byte</span>(s1)
fmt.Println(b) <span class="hljs-comment">// [65 240 159 153 130]</span>
</code></pre>
<p>Here in the above example:</p>
<ul>
<li><p>A → 65</p>
</li>
<li><p>and the other bytes are for emojis.</p>
</li>
</ul>
<p>So, a rune is what Go uses to correctly handle multilingual text and emojis.</p>
<h2 id="heading-string-bytes-and-runes-the-comparison">String, Bytes, and Runes - The Comparison</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>Underlying Type</td><td>Represents</td><td>Use Case</td></tr>
</thead>
<tbody>
<tr>
<td>string</td><td>Read-only slice of bytes</td><td>UTF-8 encoded text</td><td>Standard text data</td></tr>
<tr>
<td>[]byte</td><td>Slice of uint8</td><td>Raw binary data</td><td>File I/O, networking, encryption</td></tr>
<tr>
<td>[]rune</td><td>Slice of int32</td><td>Unicode code points</td><td>Character-level manipulation</td></tr>
</tbody>
</table>
</div><h2 id="heading-iterating-over-strings">Iterating Over Strings</h2>
<p>When you use a for loop to range over a string, Go automatically decodes UTF-8 and gives you each rune, not each byte.</p>
<pre><code class="lang-go">s := <span class="hljs-string">"Go🙂"</span>
<span class="hljs-keyword">for</span> i, r := <span class="hljs-keyword">range</span> s {
    fmt.Printf(<span class="hljs-string">"%d: %c\n"</span>, i, r)
}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-go"><span class="hljs-number">0</span>: G
<span class="hljs-number">1</span>: o
<span class="hljs-number">3</span>: 🙂
</code></pre>
<p>Notice how the emoji starts at index 3, not 2, because the emoji is 4 bytes long. This is Go’s built-in way of helping you iterate over characters safely, even for complex text.</p>
<h2 id="heading-common-pitfalls">Common Pitfalls</h2>
<ol>
<li><p><code>len(s)</code> <strong>Gives Bytes, Not Characters</strong></p>
<pre><code class="lang-go"> s := <span class="hljs-string">"🙂🙂🙂"</span>
 fmt.Println(<span class="hljs-built_in">len</span>(s))                 <span class="hljs-comment">// 12</span>
 fmt.Println(utf8.RuneCountInString(s)) <span class="hljs-comment">// 3</span>
</code></pre>
<p> Use <code>utf8.RuneCountInString</code> from the unicode / utf8 package when you want the character count, not byte count.</p>
</li>
</ol>
<p><strong>Strings Are Immutable</strong></p>
<p>You can’t modify a string directly</p>
<pre><code class="lang-go">s := <span class="hljs-string">"Go"</span>
s[<span class="hljs-number">0</span>] = <span class="hljs-string">'N'</span> <span class="hljs-comment">// ❌ compile-time error</span>
</code></pre>
<p>Instead, convert to a slice, modify and convert back:</p>
<pre><code class="lang-go">b := []<span class="hljs-keyword">byte</span>(s)
b[<span class="hljs-number">0</span>] = <span class="hljs-string">'N'</span>
s = <span class="hljs-keyword">string</span>(b)
fmt.Prinln(s) <span class="hljs-comment">// "NO"</span>
</code></pre>
<h2 id="heading-understanding-the-memory-representation">Understanding the Memory Representation</h2>
<p>Here’s how Go internally stores and interprets text</p>
<pre><code class="lang-go">String: <span class="hljs-string">"Go🙂"</span>

Bytes: [<span class="hljs-number">71</span> <span class="hljs-number">111</span> <span class="hljs-number">240</span> <span class="hljs-number">159</span> <span class="hljs-number">153</span> <span class="hljs-number">130</span>]
Runes: [<span class="hljs-number">71</span> <span class="hljs-number">111</span> <span class="hljs-number">128578</span>]

<span class="hljs-string">'G'</span>   = <span class="hljs-number">1</span> <span class="hljs-keyword">byte</span>
<span class="hljs-string">'o'</span>   = <span class="hljs-number">1</span> <span class="hljs-keyword">byte</span>
<span class="hljs-string">'🙂'</span>  = <span class="hljs-number">4</span> bytes
</code></pre>
<h2 id="heading-when-to-use-what">When to Use What</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Use Case</strong></td><td><strong>Best Type</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Normal text processing</td><td>string</td></tr>
<tr>
<td>Raw binary I/O (files, sockets, hashing)</td><td>[]byte</td></tr>
<tr>
<td>Character-by-Character operations</td><td>[]rune</td></tr>
<tr>
<td>Counting or slicing Unicode text</td><td>utf8.RuneCountInString</td></tr>
</tbody>
</table>
</div><h2 id="heading-why-this-matters">Why This Matters?</h2>
<p>Understanding strings, bytes, and runes helps you:</p>
<ul>
<li><p>Avoid bugs with Unicode text.</p>
</li>
<li><p>Handle emojis and multilingual input correctly.</p>
</li>
<li><p>Optimize performance when dealing with files or network data.</p>
</li>
<li><p>Build a mental model of Go’s memory representation.</p>
</li>
</ul>
<p>This is one of those small topics that quietly separates beginner Go programmers from intermediate ones.</p>
<h3 id="heading-quick-recap">Quick Recap</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Concept</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td>String</td><td>Immutable sequence of bytes (UTF-8 encoded)</td></tr>
<tr>
<td>Byte</td><td>Represents one raw byte of data (uint8)</td></tr>
<tr>
<td>Rune</td><td>Represents a single Unicode code point (int32)</td></tr>
<tr>
<td>Tip</td><td>Always remember: 1 character is not equal to 1 byte in UTF-8</td></tr>
</tbody>
</table>
</div><h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, working with text in Go involves understanding the intricate relationship between strings, bytes, and runes, all of which are underpinned by UTF-8 encoding. This system allows Go to efficiently handle a wide range of characters, from simple ASCII to complex Unicode symbols like emojis. By grasping these concepts, you can effectively manage text data, avoid common pitfalls, and ensure your applications are robust and capable of handling multilingual and emoji-rich content. This knowledge is crucial for developing efficient and reliable Go programs, setting apart beginner programmers from those with a deeper understanding of the language's text processing capabilities.</p>
]]></content:encoded></item><item><title><![CDATA[Memory Management in Go -- Explained Like How your Brain Works]]></title><description><![CDATA[Welcome back to my Go Deep with Golang series!
In the last couple of blog posts, we delved into some fundamental concepts that are essential for anyone looking to get started with programming in Go. We covered how to declare variables, explored the v...]]></description><link>https://blog.rohitlokhande.in/memory-management-in-go-explained-like-how-your-brain-works</link><guid isPermaLink="true">https://blog.rohitlokhande.in/memory-management-in-go-explained-like-how-your-brain-works</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[pointers in Go]]></category><category><![CDATA[memory-management]]></category><category><![CDATA[memory management in go]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Tue, 28 Oct 2025 18:42:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761592601857/e1a92b87-891f-4ad9-a30e-f013c01fbd84.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back to my Go Deep with Golang series!</p>
<p>In the last couple of blog posts, we delved into some fundamental concepts that are essential for anyone looking to get started with programming in Go. We covered how to declare variables, explored the various data types available, and examined control flow mechanisms such as loops and conditionals. Additionally, we discussed functions, which are crucial for organizing code and promoting reusability. These topics form the foundational building blocks necessary for creating robust and efficient programs in Go.</p>
<p>Now, as we continue our journey, it's time to explore one of the most critical and intriguing concepts in the Go programming language: Pointers. Understanding pointers is vital for grasping how Go manages variables and memory allocation behind the scenes. In this post, we will take a closer look at what pointers are, how they work, and why they are so important in Go. We will also discuss how pointers can be used to optimize performance and manage resources effectively. If you've ever been curious about the inner workings of Go's memory management, this post will provide you with a comprehensive explanation and equip you with the knowledge to use pointers confidently in your Go programs.</p>
<h2 id="heading-the-brain-analogy">The Brain Analogy</h2>
<p>Imagine your brain managing information like this:</p>
<ul>
<li><p>Your short-term memory helps you quickly process what's needed right now.</p>
</li>
<li><p>Your long-term memory stores information you'll need later.</p>
</li>
<li><p>Your subconscious decides when to remember or forget.</p>
</li>
</ul>
<p>Go works in a similar way:</p>
<ul>
<li><p>Stack (Short-term memory): Like short-term memory in the brain, it's fast, temporary storage for active function calls.</p>
</li>
<li><p>Heap (Long-term memory): It's slower, persistent storage managed by the garbage collector.</p>
</li>
<li><p>Go Runtime (Subconscious brain): Decides where to store data and when to clean it up.</p>
</li>
</ul>
<p>Let's dive deeper into each term.</p>
<h2 id="heading-stack-gos-short-term-memory">Stack - Go’s Short-Term Memory</h2>
<p>When you call a function in Go, it gets its own stack frame. This is where local variables, parameters, and return addresses reside.</p>
<p>After the execution of a function, Go automatically clears the stack frame—no manual cleanup required.</p>
<p><strong>Example</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">add</span><span class="hljs-params">(a,b <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    sum := a + b
    <span class="hljs-keyword">return</span> sum
}
</code></pre>
<p>In the above example,</p>
<ul>
<li><p>The data for <code>a</code>, <code>b</code>, and <code>sum</code> will live on the stack.</p>
</li>
<li><p>When <code>add()</code> returns, all of them are automatically destroyed.</p>
</li>
<li><p>Stack allocation is super fast because it’s managed like a simple “move up or down” pointer in memory.</p>
</li>
</ul>
<h2 id="heading-heap-gos-long-term-memory">Heap - Go’s Long-Term Memory</h2>
<p>Now, what if your data needs to outlive a function call?</p>
<p>In that case, Go moves it to the heap memory. These heap allocations are managed by the Garbage Collector.</p>
<p><strong>Example</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">newInt</span><span class="hljs-params">()</span> *<span class="hljs-title">int</span></span> {
    x := <span class="hljs-number">42</span>
    <span class="hljs-keyword">return</span> &amp;x <span class="hljs-comment">// returning a pointer</span>
}
</code></pre>
<p>In this,</p>
<ul>
<li><p>x escapes to the heap because its pointer is returned.</p>
</li>
<li><p>The pointer itself (&amp;x) lives on the stack, but</p>
</li>
<li><p>The actual data x= 42 lives on the heap.</p>
</li>
</ul>
<h2 id="heading-pointers-the-memory-address-messengers">Pointers — The Memory Address Messengers</h2>
<p>A pointer is like your brain remembering where a fact is stored, not the fact itself.</p>
<p>Example:</p>
<pre><code class="lang-go">a := <span class="hljs-number">10</span>
p := &amp;a
</code></pre>
<ul>
<li><p><code>a</code> holds the value 10.</p>
</li>
<li><p><code>p</code> holds the address of a.</p>
</li>
</ul>
<p>When you use <code>*p</code>, you’re saying “go to this address and read the value.“</p>
<h2 id="heading-garbage-collector-the-brains-cleanup-crew">Garbage Collector - The Brain’s Cleanup Crew</h2>
<p>The Garbage Collector is like your brain's cleanup process—it removes data you no longer use.</p>
<p>Go uses a concurrent tri-color mark-and-sweep garbage collector for cleanup.</p>
<ol>
<li><p><strong>Mark Phase:</strong></p>
<p> The GC scans your program's active references (roots) and marks reachable objects as "in use."</p>
</li>
<li><p><strong>Sweep Phase:</strong></p>
<p> It removes any unmarked (unreachable) objects and reclaims their memory.</p>
</li>
<li><p><strong>Concurrent Execution:</strong></p>
<p> This happens alongside your running program, so Go apps rarely pause for the Garbage Collector.</p>
</li>
<li><p><strong>Write Barrier:</strong></p>
<p> When the Garbage Collector and your program run together, write barriers ensure memory consistency, so no pointer gets lost during cleanup.</p>
</li>
</ol>
<p>We will explore this in more detail in another article that will focus solely on the garbage collector.</p>
<h2 id="heading-escape-analysis-gos-subconscious-decision-maker">Escape Analysis - Go’s Subconscious Decision-Maker</h2>
<p>Escape analysis is a process that Go uses during compilation to decide where a variable should be stored in memory, either on the stack or the heap.</p>
<p>In simple terms, escape analysis checks, "Does this variable leave its current function or not?"</p>
<ul>
<li><p>If yes, it stores it on the heap so it remains after the function returns.</p>
</li>
<li><p>If no, it keeps it on the stack, which is faster and automatically cleaned up when the function ends..</p>
</li>
</ul>
<h3 id="heading-why-go-needs-escape-analysis">Why Go Needs Escape Analysis</h3>
<p>Unlike C++, Go doesn’t allow you to manually decide where to allocate memory. Therefore, the compiler must make that decision automatically. This is important because:</p>
<ul>
<li><p>Stack allocation is cheap and automatically cleaned up.</p>
</li>
<li><p>Heap allocations are slower and managed by the Garbage Collector.</p>
</li>
</ul>
<p>Escape analysis helps Go minimize GC pressure and improve performance.</p>
<p>Let’s understand this with some examples.</p>
<p><strong>Example 1 - No Escape (Stack Allocation)</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">add</span><span class="hljs-params">(a, b <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    sum := a + b
    <span class="hljs-keyword">return</span> sum
}
</code></pre>
<p>Here,</p>
<ul>
<li><p><code>a</code>, <code>b</code>, and <code>sum</code> all stay on the stack.</p>
</li>
<li><p>Nothing "escapes" the function—Go removes them as soon as <code>add()</code> returns.</p>
</li>
</ul>
<p>This is fast and efficient. There's no involvement from the Garbage Collector here.</p>
<p><strong>Example 2 - Variable Escapes (Heap Allocation)</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">newInt</span><span class="hljs-params">()</span> *<span class="hljs-title">int</span></span> {
    x := <span class="hljs-number">42</span>
    <span class="hljs-keyword">return</span> &amp;x
}
</code></pre>
<p>Here’s what happens:</p>
<ul>
<li><p><code>x</code> is created inside <code>newInt()</code>, but we return its pointer.</p>
</li>
<li><p>The variable <code>x</code> must exist after the function ends because it's used outside.</p>
</li>
<li><p>So, Go moves <code>x</code> from the stack to the heap.</p>
</li>
</ul>
<p>This is called <strong>escaping to the heap</strong>.</p>
<p><strong>Example 3 — Pointer Inside Function (No Escape)</strong></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">pointerInside</span><span class="hljs-params">()</span></span> {
    x := <span class="hljs-number">42</span>
    p := &amp;x
    fmt.Println(*p)
}
</code></pre>
<p>In this example:</p>
<ul>
<li><p>The <code>x</code> variable does not escape, even though we use a pointer.</p>
</li>
<li><p>The pointer <code>p</code> never leaves the function. It is used only inside that function.</p>
</li>
<li><p>So, both <code>x</code> and <code>p</code> stay on the stack.</p>
</li>
</ul>
<p>From this example, we understand that using a pointer does not always mean heap allocation.</p>
<h3 id="heading-how-to-check-escape-analysis-in-action">How to Check Escape Analysis in Action</h3>
<p>You can see what Go decides using the compiler flag</p>
<pre><code class="lang-bash">go build -gcflags=<span class="hljs-string">"-m"</span> main.go
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-bash">./main.go:5:6: moved to heap: x
</code></pre>
<p>This means: The variable <code>x</code> “escaped“ to the heap because its pointer was returned.</p>
<h3 id="heading-common-escape-patterns">Common Escape Patterns</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Code Pattern</strong></td><td>Escapes</td><td>Reason</td></tr>
</thead>
<tbody>
<tr>
<td>Returning a pointer</td><td>Yes</td><td>Needs to live beyond the function</td></tr>
<tr>
<td>Captured by a closure</td><td>Yes</td><td>Closure may outlive function</td></tr>
<tr>
<td>Stored in a global variable</td><td>Yes</td><td>Accessible after function returns</td></tr>
<tr>
<td>Passed to a function that might store it</td><td>Often</td><td>Compilter can’t guarantee it won’t escape</td></tr>
<tr>
<td>Used only within function</td><td>No</td><td>Safe to stay on stack</td></tr>
</tbody>
</table>
</div><h3 id="heading-how-escape-analysis-helps-gos-performance">How Escape Analysis Helps Go’s Performance</h3>
<ul>
<li><p>Avoid unnecessary heap allocations.</p>
</li>
<li><p>Reduce Garbage Collector overhead.</p>
</li>
<li><p>Optimize runtime performance.</p>
</li>
</ul>
<p>Let's explore this further with a detailed example using the code below.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">newInt</span><span class="hljs-params">()</span> *<span class="hljs-title">int</span></span> {
    x := <span class="hljs-number">42</span>
    <span class="hljs-keyword">return</span> &amp;x <span class="hljs-comment">// returning a pointer</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    p := newInt()
    fmt.Println(*p) <span class="hljs-comment">// prints 42</span>

    a := <span class="hljs-number">1</span>
    b := &amp;a
    fmt.Println(b)
}
</code></pre>
<p>After running the command <code>go build -gcflags="-m" main.go</code>, you will receive the following analysis:</p>
<pre><code class="lang-bash">./main.go:4:6: can inline newInt
./main.go:9:16: inlining call to newInt
./main.go:10:16: inlining call to fmt.Println
./main.go:13:13: inlining call to fmt.Println
./main.go:5:5: moved to heap: x
./main.go:11:2: moved to heap: a
./main.go:10:16: ... argument does not escape
./main.go:10:17: *p escapes to heap
./main.go:13:13: ... argument does not escape
</code></pre>
<p>Let's break down the example step by step:</p>
<ol>
<li><p><strong>Function</strong> <code>newInt()</code>:</p>
<pre><code class="lang-go"> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">newInt</span><span class="hljs-params">()</span> *<span class="hljs-title">int</span></span> {
     x := <span class="hljs-number">42</span>
     <span class="hljs-keyword">return</span> &amp;x
 }
</code></pre>
<ul>
<li><p><code>x</code> is a local variable inside the <code>newInt</code> function. Typically, local variables reside on the stack, and their memory is freed once the function execution completes. However, in this case, we return the address (<code>&amp;x</code>) of <code>x</code>, meaning the pointer will outlive the function's scope. Since <code>main()</code> needs to access it after <code>newInt()</code> returns, Go performs escape analysis and determines that <code>x</code> cannot remain on the stack. It must be moved to the heap to stay valid for the pointer <code>p</code>.</p>
</li>
<li><p><strong>Compiler Output</strong>: <code>./main.go:5:5: moved to heap: x</code></p>
</li>
</ul>
</li>
<li><p><strong>Pointer</strong> <code>p</code>:</p>
<pre><code class="lang-go"> p := newInt()
</code></pre>
<ul>
<li><p>The call to <code>newInt()</code> returns a pointer to an integer stored on the heap. The pointer variable <code>p</code> is stored on the stack in <code>main()</code>, but the data it points to (<code>x</code>) resides on the heap.</p>
</li>
<li><p><strong>Compiler Output</strong>: <code>./main.go:10:17: *p escapes to heap</code></p>
</li>
</ul>
</li>
<li><p><strong>Dereferencing</strong> <code>p</code>:</p>
<pre><code class="lang-go"> fmt.Println(*p)
</code></pre>
<ul>
<li><p><code>*p</code> dereferences the pointer to print the integer value. The argument <code>(*p)</code> does not escape, meaning <code>fmt.Println</code> only reads it and does not retain a reference beyond the call.</p>
</li>
<li><p><strong>Compiler Output</strong>: <code>./main.go:10:16: ... argument does not escape</code></p>
</li>
</ul>
</li>
<li><p><strong>Variables</strong> <code>a</code> and <code>b</code>:</p>
<pre><code class="lang-go"> a := <span class="hljs-number">1</span>
 b := &amp;a
 fmt.Println(b)
</code></pre>
<ul>
<li><p><code>a</code> is a local stack variable in <code>main()</code>. When you take its address (<code>b := &amp;a</code>) and pass <code>b</code> to <code>fmt.Println</code>, the compiler conservatively assumes that <code>a</code> might escape because it cannot guarantee that <code>fmt.Println</code> won’t keep a reference to it. Therefore, <code>a</code> is moved to the heap to be safe, even though <code>fmt.Println</code> does not retain the reference.</p>
</li>
<li><p><strong>Compiler Output</strong>:</p>
<ul>
<li><p><code>./main.go:11:2: moved to heap: a</code></p>
</li>
<li><p><code>./main.go:13:13: ... argument does not escape</code></p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>This example illustrates how Go's escape analysis works to determine whether variables should be allocated on the stack or the heap, ensuring memory safety and efficiency.</p>
<h2 id="heading-relationship-between-pointers-and-memory-management">Relationship Between Pointers and Memory Management</h2>
<p>Now, let’s connect the dots.</p>
<ol>
<li><p><strong>Pointers control where data lives</strong></p>
<p> When you take a pointer <code>(&amp;x)</code>, you’re telling GO</p>
<p> <code>“Hey“, I want to keep track of this memory location.”</code></p>
<p> Go checks if that pointer escapes its current scope:</p>
<ul>
<li><p>If it doesn’t → keep it on the stack.</p>
</li>
<li><p>If it does → move it to the heap.</p>
</li>
</ul>
</li>
<li><p><strong>Pointers influence garbage collection</strong></p>
<p> If you still have a pointer to an object, the Garbage Collector won’t delete it.</p>
<p> Once no active pointer references a heap object → It’s eligible for the Garbage Collector.</p>
</li>
<li><p><strong>Pointer Storage location</strong></p>
<ul>
<li><p>The pointer variable itself (the address holder) is stored where it’s declared, usually on the stack.</p>
</li>
<li><p>The data being pointed to might be on the stack or heap, depending on escape analysis.</p>
</li>
</ul>
</li>
</ol>
<ol>
<li><ul>
<li><pre><code class="lang-go">   <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">example</span><span class="hljs-params">()</span> *<span class="hljs-title">int</span></span> {
       a := <span class="hljs-number">10</span>   <span class="hljs-comment">// 'a' lives on stack initially</span>
       p := &amp;a   <span class="hljs-comment">// 'p' (pointer) lives on stack</span>
       <span class="hljs-keyword">return</span> p  <span class="hljs-comment">// 'a' moves to heap because 'p' escapes</span>
   }
</code></pre>
</li>
</ul>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761592154947/c59ffd35-765a-42f7-b030-4212a0d7188c.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-stack-shrinking-and-growth">Stack Shrinking and Growth</h2>
<p>Go’s stack isn’t fixed in size. Each goroutine starts with a small stack (2kb) and grows dynamically as needed.</p>
<p>When a function call needs more space:</p>
<ul>
<li><p>Go allocates a bigger stack.</p>
</li>
<li><p>Copies the current stack content into it.</p>
</li>
<li><p>Updates all stack pointers accordingly.</p>
</li>
</ul>
<p>This flexibility ensures efficient memory usage across thousands of goroutines.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, understanding Go's memory management is akin to understanding how our brain processes and stores information. By grasping the concepts of stack and heap memory, pointers, and escape analysis, you can write more efficient and optimized Go programs. This knowledge allows you to make informed decisions about memory allocation, helping to minimize unnecessary heap allocations and reduce the overhead of the garbage collector. Just as our brain seamlessly manages short-term and long-term memories, Go efficiently handles memory allocation and cleanup, allowing you to focus on building robust applications. Embracing these concepts will empower you to harness the full potential of Go's performance capabilities.</p>
]]></content:encoded></item><item><title><![CDATA[Functions in Go - Organise your Code Like a Pro]]></title><description><![CDATA[Welcome back to the “Go Deep with Golang“ series!
In this blog post, we will dive into the concept of Functions in Go, a powerful feature that significantly enhances code reusability and efficiency. Functions in Go allow developers to encapsulate a s...]]></description><link>https://blog.rohitlokhande.in/functions-in-go-organise-your-code-like-a-pro</link><guid isPermaLink="true">https://blog.rohitlokhande.in/functions-in-go-organise-your-code-like-a-pro</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[learn in public]]></category><category><![CDATA[functions-in-go]]></category><category><![CDATA[go functions]]></category><category><![CDATA[Golang developer]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Fri, 24 Oct 2025 15:04:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761318021747/ae49390b-64f4-47ad-b0c2-8ecbee68d8c2.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back to the “Go Deep with Golang“ series!</p>
<p>In this blog post, we will dive into the concept of Functions in Go, a powerful feature that significantly enhances code reusability and efficiency. Functions in Go allow developers to encapsulate a set of instructions or logic that can be executed whenever needed, without having to rewrite the same code multiple times. This not only makes the codebase cleaner and more organized but also reduces the chances of errors and inconsistencies. We will explore how to define functions, pass parameters, return values, and even how to work with anonymous functions and closures. By the end of this post, you will have a comprehensive understanding of how to effectively utilize functions in your Go programming projects to create more modular and maintainable code.</p>
<p>Functions help you break code into reusable blocks, making your program modular, readable, and maintainable.<br />Go also treats functions as first-class citizens, giving you flexibility in how you pass and use them.</p>
<p>Let’s explore everything you need to know about functions in Go.Basic Function Definition</p>
<p>Syntax</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">functionName</span><span class="hljs-params">(parameters)</span> <span class="hljs-title">returnType</span></span> {
    <span class="hljs-comment">// function body</span>
    <span class="hljs-keyword">return</span> value
}
</code></pre>
<p>Example</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">add</span><span class="hljs-params">(a <span class="hljs-keyword">int</span>, b <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    <span class="hljs-keyword">return</span> a+b
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    result := add(<span class="hljs-number">5</span>,<span class="hljs-number">3</span>)
    fmt.Println(<span class="hljs-string">"Sum:"</span>,result)
}

<span class="hljs-comment">// Output</span>
<span class="hljs-comment">// Sum: 8</span>
</code></pre>
<h2 id="heading-function-parameters">Function Parameters</h2>
<p>Multiple Parameters of Same Type</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">greet</span><span class="hljs-params">(firstName, lastName <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello "</span> + firstName + <span class="hljs-string">" "</span> + lastName
}
</code></pre>
<p>Multiple Parameters of Different Types</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">info</span><span class="hljs-params">(name <span class="hljs-keyword">string</span>, age <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"%s is %d years old"</span>,name,age)
}
</code></pre>
<h2 id="heading-return-value">Return Value</h2>
<p>Single Return Value</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">square</span><span class="hljs-params">(x <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    <span class="hljs-keyword">return</span> x * x
}
</code></pre>
<p>Multiple Return Values</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">divide</span><span class="hljs-params">(a,b <span class="hljs-keyword">int</span>)</span> <span class="hljs-params">(<span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>)</span></span> {
    quotient := a/b
    remainder := a % b
    <span class="hljs-keyword">return</span> quotient, remainder
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    q, r := divide(<span class="hljs-number">10</span>,<span class="hljs-number">3</span>)
    fmt.Println(<span class="hljs-string">"Quotient:"</span>,q,<span class="hljs-string">"Remainder:"</span>,r)
}
</code></pre>
<h2 id="heading-named-return-values">Named Return Values</h2>
<p>You can name return variables directly in the function signature</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">addAddSubtract</span><span class="hljs-params">(a,b <span class="hljs-keyword">int</span>)</span> <span class="hljs-params">(sum <span class="hljs-keyword">int</span>, diff <span class="hljs-keyword">int</span>)</span></span> {
    sum = a + b
    diff = a - b
    <span class="hljs-keyword">return</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    s,d := addAndSubract(<span class="hljs-number">10</span>,<span class="hljs-number">5</span>)
    fmt.Println(s,d) <span class="hljs-comment">// 15 5</span>
}
</code></pre>
<p>In the example above, we have given names to the return values when declaring the function. This means that in the function body, we only need to assign data to those variables. At the end of the function, they are automatically returned. In the example, we declared two return variables, <code>sum</code> and <code>diff</code>, and assigned values to them within the function body. As a result, when the function is executed, we get the values of <code>sum</code> and <code>diff</code>.</p>
<h2 id="heading-variadic-functions">Variadic Functions</h2>
<p>Functions can accept any number of arguments using <code>. . .</code></p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sumAll</span><span class="hljs-params">(numbers ...<span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    sum := <span class="hljs-number">0</span>
    <span class="hljs-keyword">for</span> _,num := <span class="hljs-keyword">range</span> numbers {
        sum += num
    }
    <span class="hljs-keyword">return</span> sum
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    total := sumAll(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>)
    fmt.Println(<span class="hljs-string">"Total:"</span>,total)
}
</code></pre>
<p>In the example above, we used <code>...int</code>, which is a variadic parameter. This allows the function to accept zero or more arguments of type <code>int</code>. Inside the function, <code>numbers</code> is treated as a slice of integers (<code>[]int</code>).</p>
<h2 id="heading-anonymous-functions">Anonymous Functions</h2>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"I am anonymous"</span>)
}() <span class="hljs-comment">// immediately invoked</span>
</code></pre>
<p>or assigned to a variable</p>
<pre><code class="lang-go">greet := <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(name <span class="hljs-keyword">string</span>)</span></span> {
    fmt.Println(<span class="hljs-string">"Hello"</span>, name)
}
greet(<span class="hljs-string">"Rohit"</span>)
</code></pre>
<h2 id="heading-functions-as-first-class-citizens">Functions as First-Class Citizens</h2>
<p>You can pass functions as arguments to other functions</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">compute</span><span class="hljs-params">(a, b <span class="hljs-keyword">int</span>,operation <span class="hljs-keyword">func</span> (<span class="hljs-keyword">int</span>,<span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span>) <span class="hljs-title">int</span></span> {
    <span class="hljs-keyword">return</span> operation(a,b)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">add</span><span class="hljs-params">(x,y <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    <span class="hljs-keyword">return</span> x + y
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">return</span> := compute(<span class="hljs-number">5</span>,<span class="hljs-number">3</span>,add)
    fmt.Println(result) <span class="hljs-comment">// 8</span>
}
</code></pre>
<h2 id="heading-defer-in-functions">Defer in Functions</h2>
<p>defer is a keyword in go which schedules a function call after the surrounding function finishes</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">defer</span> fmt.<span class="hljs-built_in">println</span>(<span class="hljs-string">"This runs last"</span>)
    fmt.Println(<span class="hljs-string">"This runs first"</span>)
}

<span class="hljs-comment">//output </span>
<span class="hljs-comment">// This runs first </span>
<span class="hljs-comment">// This runs last</span>
</code></pre>
<p>This is useful for cleanup tasks like closing files or releasing resources.</p>
<h2 id="heading-higher-order-functions">Higher-Order Functions</h2>
<p>Functions that return another function.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">multiplier</span><span class="hljs-params">(x <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">func</span><span class="hljs-params">(<span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(y <span class="hljs-keyword">int</span>)</span> <span class="hljs-title">int</span></span> {
        <span class="hljs-keyword">return</span> x * y
    }
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    double := multiplier(<span class="hljs-number">2</span>)
    fmt.Println(double(<span class="hljs-number">5</span>)) <span class="hljs-comment">// 10</span>
}
</code></pre>
<h2 id="heading-closure-in-go">Closure in Go</h2>
<p>Closure is a function that captures variables from its surroundings scope.</p>
<pre><code class="lang-go">function counter() <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span> <span class="hljs-title">int</span></span> {
    count := <span class="hljs-number">0</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span> <span class="hljs-title">int</span></span> {
        count++
        <span class="hljs-keyword">return</span> count
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    c := counter()
    fmt.Println(c()) <span class="hljs-comment">//1</span>
    fmt.Println(c()) <span class="hljs-comment">//2</span>
}
</code></pre>
<p>This will used a lot in Go for maintaining state within functions.</p>
<h2 id="heading-init-function">Init Function</h2>
<p>A special function that runs automatically when a package is initialized. It run before the main() function. Making it ideal for performing setup tasks, such as configuring variables, establishing database connections, or registering services.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">init</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"This runs before main()"</span>)
}
</code></pre>
<h3 id="heading-key-characteristics-of-init">Key characteristics of init()</h3>
<ul>
<li><p>No arguments or return values</p>
</li>
<li><p>Automatic execution</p>
</li>
<li><p>Multiple <code>init()</code></p>
</li>
<li><p>Guaranteed order of execution</p>
<ul>
<li><p>Packages: The <code>init()</code> functions of imported packages are executed before the <code>init()</code> functions of the main package</p>
</li>
<li><p>Wishing a package: Go initialises variables and constants first, and then runs the <code>init()</code> functions. If there are multiple <code>init()</code> functions, they are executed in the order they appear in the source file. if spread across multiple files, they are run in alphabetical order of the filenames.</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Functions in Go are the backbone of clean, modular programming.<br />With the flexibility to return multiple values, accept variable arguments, and even be passed as parameters, functions make Go both simple and powerful.</p>
<p>Once you master functions, you can start building more organized, reusable, and maintainable programs.</p>
]]></content:encoded></item><item><title><![CDATA[Control Flow in Go - Making Decisions and Loops Easy]]></title><description><![CDATA[Welcome back to the “Go Deep with Golang” series.
In the previous blogs, we covered the basics of Go, including variables, constants, and data types.
Now, it's time to explore one of the most important aspects of any programming language.
Control Flo...]]></description><link>https://blog.rohitlokhande.in/control-flow-in-go-making-decisions-and-loops-easy</link><guid isPermaLink="true">https://blog.rohitlokhande.in/control-flow-in-go-making-decisions-and-loops-easy</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[learn in public]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Fri, 24 Oct 2025 09:38:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761290853976/3fc22ee0-82ad-4be6-9ddf-27b71b47f8d3.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back to the “Go Deep with Golang” series.</p>
<p>In the previous blogs, we covered the basics of Go, including variables, constants, and data types.</p>
<p>Now, it's time to explore one of the most important aspects of any programming language.</p>
<h2 id="heading-control-flow">Control Flow</h2>
<p>Control flow determines how your program makes decisions and repeats tasks. It helps decide what runs, when it runs, and how often it runs.</p>
<p>Let's explore all the control structures with their code snippets.</p>
<h2 id="heading-conditional-statements-in-go">Conditional Statements in Go</h2>
<p>The <code>if</code> statement</p>
<pre><code class="lang-go">poackage main
<span class="hljs-keyword">import</span> <span class="hljs-string">'fmt'</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   num := <span class="hljs-number">10</span>
   <span class="hljs-keyword">if</span> num &gt; <span class="hljs-number">0</span> {
     fmt.Println(<span class="hljs-string">"Positive number"</span>)
   }
}
</code></pre>
<h3 id="heading-short-statement-in-if">Short Statement in if</h3>
<p>Go allows variable initialization directly inside if.</p>
<pre><code class="lang-go"><span class="hljs-keyword">if</span> num:= <span class="hljs-number">10</span>; num %<span class="hljs-number">2</span> == <span class="hljs-number">0</span> {
    fmt.Println(<span class="hljs-string">"Even number"</span>)
} <span class="hljs-keyword">else</span> {
    fmt.Println(<span class="hljs-string">"Odd numner"</span>)
}
</code></pre>
<p>The variable number is scoped only inside this if block.</p>
<h2 id="heading-loops-in-go">Loops in GO</h2>
<p>Go has only one loop, the for loop, but it's extremely flexible. You can use it as a traditional loop, a while-loop, or even create infinite loops.</p>
<h3 id="heading-traditional-for-loop">Traditional for Loop</h3>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">5</span>; i++ {
  fmt.Println(i)
}
</code></pre>
<p>Structure of this for loop code</p>
<ul>
<li><p>initialisation → i := 1</p>
</li>
<li><p>Condition → i &lt;= 5</p>
</li>
<li><p>Post statement → i++</p>
</li>
</ul>
<h3 id="heading-while-like-for-loop">While-like for Loop</h3>
<p>You can skip initialisation and post expression.</p>
<pre><code class="lang-go">i := <span class="hljs-number">1</span>
<span class="hljs-keyword">for</span> i &lt;= <span class="hljs-number">5</span> {
    fmt.Println(i)
    i++
}
</code></pre>
<h3 id="heading-infinite-loop">Infinite Loop</h3>
<p>Omit all parts of for to create an infinite loop</p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> {
   fmt.Println(<span class="hljs-string">"Running.."</span>)
   <span class="hljs-keyword">break</span>
}
</code></pre>
<h2 id="heading-switch-statement">Switch Statement</h2>
<pre><code class="lang-go">day := <span class="hljs-number">3</span>
<span class="hljs-keyword">switch</span> day {
<span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:
    fmt.Println(<span class="hljs-string">"Monday"</span>)
<span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:
    fmt.Println(<span class="hljs-string">"Tuesday"</span>)
<span class="hljs-keyword">case</span> <span class="hljs-number">3</span>:
    fmt.Println(<span class="hljs-string">"Wednesday"</span>)
<span class="hljs-keyword">default</span>:
    fmt.Println(<span class="hljs-string">"Invalid day"</span>)
}
</code></pre>
<h2 id="heading-unique-features-of-switch-in-go">Unique Features of switch in Go</h2>
<ul>
<li><p>No break needed - Go automatically breaks after each case.</p>
</li>
<li><p>Multiple values per case:</p>
<ul>
<li><pre><code class="lang-go">  day :=<span class="hljs-number">3</span>
  <span class="hljs-keyword">switch</span> day {
      <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>:
        fmt.Println(<span class="hljs-string">"Weekday"</span>)
      <span class="hljs-keyword">case</span> <span class="hljs-number">6</span>,<span class="hljs-number">7</span>:
        fmt.Println(<span class="hljs-string">"Weekend"</span>)
  }
</code></pre>
</li>
</ul>
</li>
<li><p>Expressionless switch - act like a chain of if-else:</p>
<pre><code class="lang-go">  num := <span class="hljs-number">42</span>
  <span class="hljs-keyword">switch</span> {
  <span class="hljs-keyword">case</span> num &lt; <span class="hljs-number">0</span>:
      fmt.Println(<span class="hljs-string">"Negative"</span>)
  <span class="hljs-keyword">case</span> num == <span class="hljs-number">0</span>:
      fmt.Println(<span class="hljs-string">"Zero"</span>)
  <span class="hljs-keyword">default</span>:
      fmt.Println(<span class="hljs-string">"Positive"</span>)
  }
</code></pre>
</li>
<li><p>fallthrough keyword - forces the execution of the next case:</p>
<pre><code class="lang-go">  <span class="hljs-keyword">switch</span> num := <span class="hljs-number">2</span>; num {
  <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:
      fmt.Println(<span class="hljs-string">"One"</span>)
  <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:
      fmt.Println(<span class="hljs-string">"Two"</span>)
      <span class="hljs-keyword">fallthrough</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">3</span>:
      fmt.Println(<span class="hljs-string">"Three"</span>)
  <span class="hljs-keyword">default</span>:
      fmt.Println(<span class="hljs-string">"Other"</span>)
  }

  <span class="hljs-comment">// Output</span>
  Two
  Three
</code></pre>
</li>
</ul>
<h2 id="heading-goto-statement">Goto Statement</h2>
<p>This allows you to jump to a labeled statement. It’s rarely used but can help in breaking out of nested loops.</p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span>; i &lt;= <span class="hljs-number">3</span>; i++ {
    <span class="hljs-keyword">for</span> j := <span class="hljs-number">1</span>; j &lt;= <span class="hljs-number">3</span>; j++ {
        <span class="hljs-keyword">if</span> i*j &gt; <span class="hljs-number">3</span> {
            <span class="hljs-keyword">goto</span> end
        }
        fmt.Println(i, j)
    }
}
end:
fmt.Println(<span class="hljs-string">"Loop ended"</span>)

<span class="hljs-comment">// output</span>
<span class="hljs-number">1</span> <span class="hljs-number">1</span>
<span class="hljs-number">1</span> <span class="hljs-number">2</span>
Loop ended
</code></pre>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Control flow in Go is designed to be simple, readable, and minimalistic, yet powerful enough to handle all logical branching and looping needs. With just a few keywords—if, for, and switch—Go provides all the flexibility most programs need.</p>
<p>Understanding these concepts builds a strong foundation for writing clean, predictable, and efficient Go code.</p>
]]></content:encoded></item><item><title><![CDATA[Basics of Variables, Constants, and Data Types in Go]]></title><description><![CDATA[In the previous article, we installed Go on our system and ran our first "Hello, World!" program. Now, in this article, we will learn about variables and data types. This is an important topic because we need to store data in memory while running the...]]></description><link>https://blog.rohitlokhande.in/basics-of-variables-constants-and-data-types-in-go</link><guid isPermaLink="true">https://blog.rohitlokhande.in/basics-of-variables-constants-and-data-types-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[data types in golang]]></category><category><![CDATA[go series]]></category><category><![CDATA[learn in public]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Fri, 24 Oct 2025 05:25:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761283239175/5980cbca-131d-4dba-807b-463c38d4f4ac.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the previous article, we installed Go on our system and ran our first "Hello, World!" program. Now, in this article, we will learn about variables and data types. This is an important topic because we need to store data in memory while running the code to reuse it throughout the program. To do that in Go, there are some rules. So let's dive deep into this.</p>
<h2 id="heading-what-are-variables-in-go">What are Variables in Go?</h2>
<p>A variable is a named memory location that stores a value.</p>
<p>In Go, we declare variables using the following syntax or keywords:</p>
<ul>
<li><p><code>var</code> keyword</p>
</li>
<li><p><code>:=</code> → using this syntax for short and fast declaration.</p>
</li>
</ul>
<h3 id="heading-declaring-variables-using-var">Declaring Variables Using <code>var</code></h3>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">var</span> name <span class="hljs-keyword">string</span> = <span class="hljs-string">"Rohit Lokhande"</span>
    <span class="hljs-keyword">var</span> age <span class="hljs-keyword">int</span> = <span class="hljs-number">25</span>
    fmt.Println(name, age)
}
</code></pre>
<h3 id="heading-declaring-variable-using-short-declaration-syntax">Declaring Variable Using Short Declaration Syntax</h3>
<pre><code class="lang-go">name := <span class="hljs-string">"Rohit"</span>
age := <span class="hljs-number">25</span>
</code></pre>
<p><code>:=</code> this will automatically infers the type based on the value.</p>
<p>Note <code>:=</code> this declaration can only be used inside functions.</p>
<h2 id="heading-grouped-variable-declaration">Grouped Variable Declaration</h2>
<pre><code class="lang-go"><span class="hljs-keyword">var</span>(
   name=<span class="hljs-string">"Rohit"</span>
   age = <span class="hljs-number">25</span>
   city = <span class="hljs-string">"Pune"</span>
)
</code></pre>
<h2 id="heading-global-vs-local-variable">Global vs Local Variable</h2>
<p>Variables declared outside any function are package-level, which are accessible within the package.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-keyword">var</span> global = <span class="hljs-string">"I am global"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   local := <span class="hljs-string">"I am local"</span>
   fmt.Println(global)
   fmt.Println(local)
}
</code></pre>
<h2 id="heading-iota-keyword">iota keyword</h2>
<p>Go uses iota to create enumerated constants easily. It is a keyword in Golang that holds an integer value.</p>
<p>It is typically used within constant declarations to generate a series of related values, incrementing by 1 for each subsequent constant.</p>
<pre><code class="lang-go"><span class="hljs-keyword">const</span> (
   Sunday = <span class="hljs-literal">iota</span>
   Monday
   Tuesday
   Wednesday
)
fmt.Println(Sunday, Monday, Tuesday) <span class="hljs-comment">// 0 1 2</span>
</code></pre>
<p>Every new line with a constant increments iota by 1. This is used widely for status codes, enums etc</p>
<h3 id="heading-using-iota-with-expressions">Using <code>iota</code> with Expressions</h3>
<p>This is also used with expressions to define more complex constant values. Let’s understand with an example. If we want to define constants representing file sizes in bytes, kilobytes, megabytes, and so on, we can achieve this in a simple way using <code>iota</code>.</p>
<pre><code class="lang-go">pacakge main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-keyword">const</span> (
  _ = <span class="hljs-literal">iota</span> <span class="hljs-comment">// Discard the first value (0)</span>
  KB = <span class="hljs-number">1</span> &lt;&lt; (<span class="hljs-number">10</span> * <span class="hljs-literal">iota</span>) <span class="hljs-comment">// 1 &lt;&lt; (10 * 1)</span>
  MB = <span class="hljs-number">1</span> &lt;&lt; (<span class="hljs-number">10</span> * <span class="hljs-literal">iota</span>) <span class="hljs-comment">// 1 &lt;&lt; (10 * 2)</span>
  GB = <span class="hljs-number">1</span> &lt;&lt; (<span class="hljs-number">10</span> * <span class="hljs-literal">iota</span>) <span class="hljs-comment">// 1 &lt;&lt; (10 * 4)</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"KB:"</span>, KB)
    fmt.Println(<span class="hljs-string">"MB:"</span>, MB)
    fmt.Println(<span class="hljs-string">"GB:"</span>, GB)
    fmt.Println(<span class="hljs-string">"TB:"</span>, TB)
}
</code></pre>
<p>In this, we use bitwise left shifts (&lt;&lt;) in conjunction with iota to calculate the constant values for different file sizes.</p>
<h2 id="heading-rules-to-remember-while-declaring-variable">Rules to Remember While Declaring Variable</h2>
<ul>
<li><p>All variables must be used otherwise Go will throws a compile-time error.</p>
</li>
<li><p>Variables are block-scoped.</p>
</li>
<li><p>You can declare multiple variable together</p>
</li>
<li><pre><code class="lang-go">  <span class="hljs-keyword">var</span> x, y = <span class="hljs-number">10</span>,<span class="hljs-number">20</span>
</code></pre>
</li>
</ul>
<h2 id="heading-why-does-go-require-you-to-use-every-declared-variable">Why does Go require you to use every declared variable?</h2>
<ul>
<li><p><strong>Catches mistakes early</strong></p>
<p>  If you declare a variable but forget to use it, the compiler will let you know right away, preventing a runtime bug from hiding that mistake.</p>
</li>
<li><p><strong>Encourages clean code</strong></p>
<p>  No unused variables mean the code is easier to read and has fewer maintenance issues.</p>
</li>
<li><p><strong>Smaller/safer binaries</strong></p>
<p>  Unused imports and values can make builds more complicated or cause unexpected problems. Not allowing them helps keep builds straightforward and predictable.</p>
</li>
</ul>
<p>Example for above rule</p>
<p>Broken- compiler error code</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   <span class="hljs-keyword">var</span> x <span class="hljs-keyword">int</span> <span class="hljs-comment">// declared but never using</span>
   y := <span class="hljs-number">10</span>   <span class="hljs-comment">// declared but never used</span>
}
</code></pre>
<p>Compiler will complain: x declared and not used</p>
<p>Fixed - use the variables</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">var</span> x <span class="hljs-keyword">int</span>
    y := <span class="hljs-number">10</span>
    x = y * <span class="hljs-number">2</span>
    fmt.Println(x) <span class="hljs-comment">// now both x and y are used</span>
}
</code></pre>
<h3 id="heading-how-to-intentionally-ignore-a-value">How to intentionally ignore a value</h3>
<p>If you we really want to discard a value, we can use the black identifier <code>_</code> . This tells the compiler “I intentionally don’t need this.“</p>
<ul>
<li><p>Ignore a return value:</p>
<pre><code class="lang-go">  x, _ := someFunc() <span class="hljs-comment">// ignore second return value</span>
</code></pre>
</li>
<li><p>Mark a value as used (silence unused variable):</p>
<pre><code class="lang-go">  <span class="hljs-keyword">var</span> x = someFunc()
  _ = x <span class="hljs-comment">// explicitly mark "x" as used so compiler won't complain</span>
</code></pre>
</li>
</ul>
<h3 id="heading-best-practices-for-unused-compile-time-error">Best Practices for Unused Compile Time Error</h3>
<ul>
<li><ul>
<li><p>If the compiler says "declared and not used," either remove the declaration or actually use the variable.</p>
<ul>
<li><p>While experimenting, <code>_ = x</code> is a quick way to silence errors, but prefer to remove dead code before committing.</p>
</li>
<li><p>For multi-value returns where only some values matter, use <code>_</code> for the ones you want to drop.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="heading-constants-in-go">Constants in Go</h2>
<p>Constant is an immutable value - once defined, it cannot be changed.</p>
<p><strong>Declaring Constants</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">const</span> PI <span class="hljs-number">3.14</span>
<span class="hljs-keyword">const</span> Greeting = <span class="hljs-string">"Hello, Go!"</span>
</code></pre>
<p>Constants can also be grouped</p>
<pre><code class="lang-go"><span class="hljs-keyword">const</span> (
    StatusOK = <span class="hljs-number">200</span>
    StatusNotFound = <span class="hljs-number">404</span>
)
</code></pre>
<p>If you try to modify a constant, Go will throw an error:</p>
<pre><code class="lang-go">PI =<span class="hljs-number">3.142145</span> <span class="hljs-comment">// ❌ compile-time error</span>
</code></pre>
<h2 id="heading-data-types-in-go">Data Types in GO</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Category</strong></td><td>Types</td><td>Example</td></tr>
</thead>
<tbody>
<tr>
<td>Numeric</td><td>int, float32,float64,complex64,complex128</td><td>var age int = 5</td></tr>
<tr>
<td>String</td><td>string</td><td>var name string = “Rohit”</td></tr>
<tr>
<td>Boolean</td><td>bool</td><td>var isDev bool = true</td></tr>
<tr>
<td>Derived</td><td>array,slice,map,struct,interface</td><td>Covered later.</td></tr>
</tbody>
</table>
</div><p>In this section, we won't dive deep into the differences between <code>float32</code>, <code>float64</code>, and other numeric types. We will discuss non-primitive data types like arrays and slices later.</p>
<h2 id="heading-type-inference">Type inference</h2>
<p>Go automatically infers type if not specified</p>
<pre><code class="lang-go">count:= <span class="hljs-number">10</span> <span class="hljs-comment">// int</span>
price:=<span class="hljs-number">99.99</span> <span class="hljs-comment">// float64</span>
message:=<span class="hljs-string">"Hello"</span> <span class="hljs-comment">// string</span>
</code></pre>
<h3 id="heading-what-is-type-inference">What is Type Inference?</h3>
<p>Type inference means Go can automatically determine the data type of a variable based on the value you assign to it, so you don’t have to explicitly write the type every time.</p>
<p>Even though Go is <strong>statically typed</strong>, meaning types are checked at compile time, not runtime, it doesn’t always require you to write them explicitly because the compiler can infer them.</p>
<h3 id="heading-rules-for-inference">Rules for Inference</h3>
<ol>
<li><p>Inference happens only during declaration, not late:</p>
<pre><code class="lang-go"> <span class="hljs-keyword">var</span> x <span class="hljs-keyword">int</span>
 x = <span class="hljs-number">10.5</span> <span class="hljs-comment">// Error - 10.5 is float64, not int</span>
</code></pre>
</li>
<li><p>You can’t mix inferred and explicit types in one declaration</p>
<pre><code class="lang-go"> <span class="hljs-keyword">var</span> a, b = <span class="hljs-number">1</span>, <span class="hljs-string">"hello"</span>   <span class="hljs-comment">// ✅ both inferred</span>
 <span class="hljs-keyword">var</span> c, d <span class="hljs-keyword">int</span> = <span class="hljs-number">1</span>, <span class="hljs-string">"hi"</span>  <span class="hljs-comment">// ❌ type mismatch for d</span>
</code></pre>
</li>
<li><p>Inference doesn’t mean dynamic typing</p>
<p> Once inferred, the type is fixed and checked at compile time.</p>
</li>
</ol>
<h2 id="heading-zero-values-for-uninitialized-variables">Zero Values for Uninitialized variables</h2>
<p>In Go, uninitialized variables are not garbage they take zero values automatically</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>Zero Value</td></tr>
</thead>
<tbody>
<tr>
<td>int, float</td><td>0</td></tr>
<tr>
<td>string</td><td>““</td></tr>
<tr>
<td>bool</td><td>false</td></tr>
<tr>
<td>pointer,slice,map</td><td>nill</td></tr>
</tbody>
</table>
</div><h2 id="heading-type-conversion">Type Conversion</h2>
<p>Go doesn’t support implicit conversions you must convert explicitly</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> a <span class="hljs-keyword">int</span> = <span class="hljs-number">10</span>
<span class="hljs-keyword">var</span> b <span class="hljs-keyword">float64</span> = <span class="hljs-keyword">float64</span>(a)
fmt.Println(b)
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Variables, constants, and data types form the foundation of any Go program. Go’s simple but strong type system encourages clean, predictable code, so you always know what’s stored where.</p>
<p>In the next post, we’ll dive into Functions in Go, where you’ll learn how to organize and reuse logic efficiently.</p>
]]></content:encoded></item><item><title><![CDATA[Why I Chose Go - Getting Started with Golang]]></title><description><![CDATA[“Simple, fast, and reliable.“
That’s how google engineers described Go when they introduced it to the world.

If you’re a developer like me exploring new backend technologies, you’ve probably heard about Golang, a language known for its speed, simpli...]]></description><link>https://blog.rohitlokhande.in/getting-started-with-golang</link><guid isPermaLink="true">https://blog.rohitlokhande.in/getting-started-with-golang</guid><category><![CDATA[Setup Go lang]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[Golang developer]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Thu, 23 Oct 2025 09:34:28 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>“Simple, fast, and reliable.“</p>
<p>That’s how google engineers described Go when they introduced it to the world.</p>
</blockquote>
<p>If you’re a developer like me exploring new backend technologies, you’ve probably heard about Golang, a language known for its speed, simplicity, and ability to handle high-performance systems.</p>
<p>In this post, I’ll share why I chose Go, how to set up your environment, and how to write your first Go program—step by step.</p>
<h2 id="heading-what-is-go">What is Go?</h2>
<p>Go is a statically typed, compiled programming language developed by Google. It was created to address modern software development issues, such as managing large, complex codebases and leveraging multicore systems effectively.</p>
<p>The language combines the performance of lower-level languages like C++ with the simplicity and productivity of languages such as Python..</p>
<h2 id="heading-key-features-of-go">Key features of Go</h2>
<ul>
<li><p><strong>Concurrency</strong></p>
<ul>
<li><p>It provides built-in support for concurrency, the ability to run multiple tasks simultaneously.</p>
</li>
<li><p>It uses lightweight threads called “goroutines” and communication channels to manage these tasks efficiently.</p>
</li>
</ul>
</li>
<li><p><strong>Simplicity and readability</strong></p>
<ul>
<li><p>Go has a clean, minimalist syntax that is easy for new developers to learn and for teams to maintain.</p>
</li>
<li><p>It enforces a consistent coding style across the entire Go ecosystem through tools like gofmt.</p>
</li>
</ul>
</li>
<li><p><strong>Fast compilation and execution</strong></p>
<ul>
<li>As a compiled language, Go produces native machine code, resulting in fast execution speed and rapid build times.</li>
</ul>
</li>
<li><p><strong>Static binaries and easy deployment</strong></p>
<ul>
<li>Go compiles into a single, static binary file that includes its own runtime, making deployment simple and portable across different platforms like Windows, macOS, and Linux.</li>
</ul>
</li>
<li><p><strong>Robust standard library</strong></p>
<ul>
<li>Go has a comprehensive standard library with a wide range of packages for common tasks like networking, web servers, and cryptography, reducing the need for external third-party libraries.</li>
</ul>
</li>
<li><p><strong>Memory safety</strong></p>
<ul>
<li>It features automatic memory management with a garbage collector, which reduces the risk of memory leaks and other common bugs.</li>
</ul>
</li>
</ul>
<h2 id="heading-when-to-choose-go">When to choose Go</h2>
<ul>
<li><p><strong>Cloud computing and microservices</strong></p>
<ul>
<li><p>Modern cloud-native tools like Docker, Kubernetes, and Terraform are written in Go.</p>
</li>
<li><p>Its lightweight nature and efficient concurrency make it ideal for microservices and cloud-based applications.</p>
</li>
</ul>
</li>
<li><p><strong>Backend services and APIs</strong></p>
<ul>
<li>It is well-suited for building high-performance web servers, APIs, and distributed systems that handle high volumes of simultaneous requests.</li>
</ul>
</li>
<li><p><strong>Command-line interfaces</strong></p>
<ul>
<li>Go's ability to compile into a single binary with no external dependencies makes it a great choice for creating fast and portable CLI tools.</li>
</ul>
</li>
<li><p><strong>DevOps and site reliability</strong></p>
<ul>
<li>Go's fast build times, simple syntax, and robust tooling make it a favorite for DevOps and site reliability engineers (SREs).</li>
</ul>
</li>
<li><p><strong>Data processing</strong></p>
<ul>
<li>With its concurrency model and memory efficiency, Go is well-suited for processing and analyzing large datasets in parallel.</li>
</ul>
</li>
</ul>
<h2 id="heading-installing-go">Installing GO</h2>
<p>Setting up Go is simple and quick</p>
<h3 id="heading-step1-download-and-install">Step1: Download and Install</h3>
<p>Go to the official site of go:</p>
<p><a target="_blank" href="https://go.dev/dl/">Download GO Installer</a></p>
<p>Choose the installer for your OS.</p>
<h3 id="heading-step-2-verify-installation">Step 2: Verify Installation</h3>
<p>After Successfully installation, Open your terminal or command prompt and check below things.</p>
<pre><code class="lang-bash">go version
</code></pre>
<p>If everything went well, you’ll see below output</p>
<pre><code class="lang-bash">go version go1.25.0 darwin/arm64
</code></pre>
<h2 id="heading-setting-up-your-first-go-project">Setting Up Your First Go Project</h2>
<p>Let’s create a workspace for your projects.</p>
<pre><code class="lang-bash">mkdir go-learning
<span class="hljs-built_in">cd</span> go-learning
mkdir hello-world &amp;&amp; <span class="hljs-built_in">cd</span> hello-world
go mod init hello-world
</code></pre>
<p>This commands will create a separate folder and Go module which helps manage dependencies and packages in your project.</p>
<h2 id="heading-writing-your-first-go-program">Writing Your First Go Program</h2>
<p>create a new file called main.go</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   fmt.Println(<span class="hljs-string">"Hello World!!"</span>)
}
</code></pre>
<p>Now, run your code using below command from directory where that file is located.</p>
<pre><code class="lang-bash">go run main.go
</code></pre>
<h2 id="heading-understanding-the-program">Understanding the Program</h2>
<p>Let’s break down what’s happening in our code:</p>
<ul>
<li><p><strong>package main</strong> → Every Go program starts with a package. The main package is special - it defines an executable program.</p>
</li>
<li><p><strong>import “fmt”</strong> → Imports Go’s format package, which contains functions for input/output (like printing).</p>
</li>
<li><p><strong>func main()</strong> → The entry point of every Go program. Execution starts here.</p>
</li>
<li><p><strong>fmt.Println()</strong> → Prints text to the console with a new line.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Learning GO feels like unlocking a new way to think about programming—clean, fast, and efficient. It strips away unnecessary complexity and helps you focus on writing code that just works.</p>
<p>Starting with “Hello World!!“ might seem small, but it’s the first step toward mastering one of the most powerful modern languages shaping cloud computing and backend systems today.</p>
<p>In the next post, I’ll explore how Go handles variables, constants, and data types, the building blocks that make your programs truly dynamic. Stay tuned—this journey is just getting started.</p>
]]></content:encoded></item><item><title><![CDATA[Easy Ways to Set Up Your Own Deep Linking System]]></title><description><![CDATA[What is Deep Linking?
Deep linking is a technique that takes users directly to a specific page or screen of an app. A deep link is simply a regular web URL. When opened in a browser, it displays a webpage, like a specific post. However, in the contex...]]></description><link>https://blog.rohitlokhande.in/easy-ways-to-set-up-your-own-deep-linking-system</link><guid isPermaLink="true">https://blog.rohitlokhande.in/easy-ways-to-set-up-your-own-deep-linking-system</guid><category><![CDATA[Firebase deeplink]]></category><category><![CDATA[Custom deep linking ]]></category><category><![CDATA[DeepLinking]]></category><category><![CDATA[Firebase]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Sun, 22 Jun 2025 17:03:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750571394196/0ed1a727-3244-45b1-8d12-f6efb750f9c5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-deep-linking">What is Deep Linking?</h2>
<p>Deep linking is a technique that takes users directly to a specific page or screen of an app. A deep link is simply a regular web URL. When opened in a browser, it displays a webpage, like a specific post. However, in the context of a mobile app, it opens the app instead of the browser.</p>
<p>Let's look at a real-world example. Imagine you're scrolling through Instagram reels in your free time and come across a funny reel you want to share with a friend. You share the reel through a link on another platform, like WhatsApp. That link is a deep link. When your friend opens the link on their mobile app and already has Instagram installed, it will open in the app. If not, it will redirect them to the Play Store to install the app—this is called deferred deep linking. If your friend opens the link in a browser on a laptop or desktop, it will redirect to the same reel in the browser.</p>
<p>Now that you understand what deep linking is, we will move on to the implementation part. Before we start, let's discuss what we will use in this process.</p>
<h2 id="heading-tech-used">Tech Used</h2>
<ul>
<li><p>React Native : We have used this to build mobile app you can use other tech as well.</p>
</li>
<li><p>Aws Ec2 : Cloud server hosting Nginx and your domain</p>
</li>
<li><p>Nginx: Web server to serve Android, IOS configuration file</p>
</li>
<li><p>Node js: Running Server with redirecting web page if application not available on mobile phone you can use any other backend tech as well instead of this.</p>
</li>
</ul>
<p>Now that we understand what we are using and the alternatives, let's start the implementation.</p>
<p>First, we will begin with the backend implementation.</p>
<h2 id="heading-creating-an-api-endpoint-in-nodejs">Creating an API Endpoint in Node.js</h2>
<h3 id="heading-appts">app.ts</h3>
<p>Add below router in app.ts file</p>
<pre><code class="lang-javascript">...OtherCode
app.use(<span class="hljs-string">"/s"</span>, deeplinkRoutes);
</code></pre>
<h3 id="heading-routesdeep-linkingroutests">routes/deep-linking.routes.ts</h3>
<p>Setup deep linking routes</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">import</span> { Router } <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> DeeplinkController <span class="hljs-keyword">from</span> <span class="hljs-string">"../controllers/deeplink.controller"</span>;
<span class="hljs-keyword">const</span> deeplinkRoutes = Router();

deeplinkRoutes.get(<span class="hljs-string">"/:id"</span>, DeeplinkController.deeplink);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> deeplinkRoutes;
</code></pre>
<h3 id="heading-controllersdeeplinkroutests">controllers/deeplink.routes.ts</h3>
<p>Create controller for deeplink</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Request, Response } <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DeeplinkController</span> </span>{
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> deeplink(
    req: Request&lt;{ <span class="hljs-attr">id</span>: string }&gt;,
    res: Response
  ) {
    <span class="hljs-keyword">const</span> { id } = req.params;
    <span class="hljs-comment">// Serve HTML page instead of JSON</span>
    <span class="hljs-keyword">const</span> htmlContent = <span class="hljs-string">`&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;title&gt;TITLE&lt;/title&gt;
  &lt;script&gt;
    // Try to open the app
    setTimeout(function() {
      window.location.href = "&lt;APP_NAME&gt;://s/<span class="hljs-subst">${id}</span>";
    }, 50);

    // Check if iOS
    var userAgent = navigator.userAgent || navigator.vendor || window.opera;
    if (/iPad|iPhone|iPod/.test(userAgent) &amp;&amp; !window.MSStream) {
      // For iOS, redirect to App Store
      setTimeout(function() {
        window.location.href = &lt;APP_STORE_LINK&gt;;
      }, 2000);
    } else {
      // For Android, redirect to Play Store
      setTimeout(function() {
        window.location.href = &lt;PLAY_STORE_LINK&gt;;
      }, 2000);
    }
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div style="text-align: center; padding-top: 100px;"&gt;
    &lt;h1&gt;Opening App...&lt;/h1&gt;
    &lt;p&gt;If the app doesn't open automatically, &lt;a href="&lt;PLAY_STORE_LINK&gt;"&gt;download it from the Play Store&lt;/a&gt; or &lt;a href="&lt;APP_STORE_LINK&gt;"&gt;App Store&lt;/a&gt;.&lt;/p&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;`</span>;

    res.setHeader(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"text/html"</span>);
    res.status(<span class="hljs-number">200</span>).send(htmlContent);
    <span class="hljs-keyword">return</span>;
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DeeplinkController;
</code></pre>
<p>This endpoint will handle redirection to the Play Store or App Store if the app is not installed on the device.</p>
<h3 id="heading-android-assetlinksjson">Android: assetlinks.json</h3>
<pre><code class="lang-json">[
  {
    <span class="hljs-attr">"relation"</span>: [<span class="hljs-string">"delegate_permission/common.handle_all_urls"</span>],
    <span class="hljs-attr">"target"</span>: {
      <span class="hljs-attr">"namespace"</span>: <span class="hljs-string">"android_app"</span>,
      <span class="hljs-attr">"package_name"</span>: <span class="hljs-string">"com.yourapp"</span>,
      <span class="hljs-attr">"sha256_cert_fingerprints"</span>: [<span class="hljs-string">"YOUR_SHA256_CERT_FINGERPRINT"</span>]
    }
  }
]
</code></pre>
<p>sha256_cert_fingerprints is used for app security. Get it using:</p>
<pre><code class="lang-plaintext">keytool -list -v -keystore my-release-key.keystore -alias my-key-alias
</code></pre>
<h3 id="heading-ios-apple-app-site-association">IOS: apple-app-site-association</h3>
<pre><code class="lang-json">{
  <span class="hljs-attr">"applinks"</span>: {
    <span class="hljs-attr">"apps"</span>: [],
    <span class="hljs-attr">"details"</span>: [
      {
        <span class="hljs-attr">"appID"</span>: <span class="hljs-string">"TEAM_ID.com.yourapp"</span>,
        <span class="hljs-attr">"paths"</span>: []
      }
    ]
  }
}
</code></pre>
<p>These two files are needed for App Links and Universal Links to verify that your app has permission to open specific links.</p>
<p>Without these rules, when a user clicks a link like “https://myapp.com/s/:id”, it will always open in the browser instead of the app.</p>
<h2 id="heading-why-are-these-files-needed">Why are these Files Needed?</h2>
<h3 id="heading-android-assetlinksjson-1">Android: assetlinks.json</h3>
<ul>
<li><p>Android needs this file to confirm that the domain (myapp.com) can open links in the app.</p>
</li>
<li><p>It stops <strong>malicious apps</strong> from pretending to own other domains.</p>
</li>
<li><p>It must be available at:</p>
<p>  <a target="_blank" href="https://myapp.com/.well-known/assetlinks.json"><strong>https://myapp.com/.well-known/assetlinks.json</strong></a></p>
</li>
</ul>
<h3 id="heading-ios-apple-app-site-association-aasa">IOS: apple-app-site-association (AASA)</h3>
<ul>
<li><p>IOS uses this file to link your domain (my app.com) with your app.</p>
</li>
<li><p>Without this file, Universal Links will not open your app.</p>
</li>
<li><p>It must be hosted at:</p>
<p>  <a target="_blank" href="https://myapp.com/.well-known/apple-app-site-association"><strong>https://myapp.com/.well-known/apple-app-site-association</strong></a></p>
</li>
</ul>
<h2 id="heading-how-do-these-files-work">How Do These Files Work?</h2>
<ul>
<li><p>A user clicks a deep link (https://myapp.com/s/asf313ehvas56dshtfoisag).</p>
</li>
<li><p>The OS checks if the app is installed:</p>
<ul>
<li><p>If installed → It looks for the assetlinks.json (Android) or AASA (iOS) file.</p>
</li>
<li><p>If verified → The app opens.</p>
</li>
<li><p>If verification fails or the app is not installed → The link opens in a web browser.</p>
</li>
</ul>
</li>
<li><p>File Verification Steps:</p>
<ul>
<li><p>Android/iOS checks https://myapp.com/.well-known/ for the file.</p>
</li>
<li><p>If the app’s package name (com.yourapp) or App ID matches, the OS allows deep linking.</p>
</li>
</ul>
</li>
</ul>
<p>Now that we understand the role of these two files, we will serve them through Nginx on an EC2 instance.Step 1: Prepare the apple-app-site-association file and assetlinks.json file</p>
<p>First, log in to the EC2 instance using SSH, then follow these steps:</p>
<h3 id="heading-create-the-well-known-directory">Create the .well-known Directory</h3>
<p>Run the following command on your EC2 instance:</p>
<pre><code class="lang-bash">sudo mkdir -p /var/www/html/.well-known
</code></pre>
<p>Now create <strong>assetlinks.json</strong> and apple-app-site-association in that path.</p>
<h3 id="heading-set-correct-permissions">Set Correct permissions</h3>
<pre><code class="lang-bash">sudo chmod 644 /var/www/html/.well-known/apple-app-site-association
sudo chown www-data:www-data /var/www/html/.well-known/apple-app-site-association
sudo chmod 644 /var/www/html/.well-known/assetlinks.json
sudo chown www-data:www-data /var/www/html/.well-known/assetlinks.json
</code></pre>
<h2 id="heading-step-2-configure-nginx-to-serve-the-file">Step 2: Configure Nginx to Serve the file</h2>
<p>Go to nginx path</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /etc/nginx
</code></pre>
<p>Create conf.d and application conf file if not available</p>
<pre><code class="lang-bash">ubuntu@EC2:/etc/nginx$ mkdir conf.d &amp;&amp; <span class="hljs-built_in">cd</span> conf.d
ubuntu@EC2:/etc/nginx/conf.d$ sudo vi app_name.conf
</code></pre>
<p>Find the server {} block and add this inside it:</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">location</span> /.well-known/assetlinks.json {
    <span class="hljs-attribute">add_header</span> Content-Type application/json;
    <span class="hljs-attribute">root</span> /var/www/html;
}
</code></pre>
<h2 id="heading-step-3-restart-nginx">Step 3: Restart Nginx</h2>
<pre><code class="lang-powershell">sudo systemctl restart nginx
</code></pre>
<p>Check if Nginx is running:</p>
<pre><code class="lang-powershell">sudo systemctl status nginx
</code></pre>
<h2 id="heading-step-4-verify-the-file-is-accessible">Step 4: Verify the File is Accessible</h2>
<p>Now, visit:</p>
<pre><code class="lang-plaintext">https://mydomain.com/.well-known/apple-app-site-association
https://mydomain.com/.well-known/assetlinks.json
</code></pre>
<blockquote>
<p>Note: Do add a SSL certificate</p>
</blockquote>
<p>With this we are done with backend implementation now let’s implement on mobile app side.</p>
<h2 id="heading-mobile-application-setup">Mobile Application Setup</h2>
<h3 id="heading-step-1-react-native-setup">Step 1: React Native Setup</h3>
<p>Install Dependencies</p>
<pre><code class="lang-bash">npm install @react-navigation/native react-native-screens react-native-safe-area-context react-native-gesture-handler
npm install react-native-reanimated
</code></pre>
<p>Configure Navigation with Deep Linking</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> linking = {
  <span class="hljs-attr">prefixes</span>: [<span class="hljs-string">'https://mydomain.com'</span>,<span class="hljs-string">'&lt;app_name&gt;://'</span>], <span class="hljs-comment">// Also added custome schema for redirection from browser</span>
  <span class="hljs-attr">config</span>: {
    <span class="hljs-attr">screens</span>: {
      <span class="hljs-attr">Home</span>: <span class="hljs-string">''</span>,
      <span class="hljs-attr">Profile</span>: <span class="hljs-string">'s/:id'</span>,
    },
  },
};

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">NavigationContainer</span> <span class="hljs-attr">linking</span>=<span class="hljs-string">{linking}</span>&gt;</span>
  {/* Your Stack Navigator */}
<span class="hljs-tag">&lt;/<span class="hljs-name">NavigationContainer</span>&gt;</span></span>
</code></pre>
<h3 id="heading-step-2-android-app-links-integration">Step 2: Android App Links Integration</h3>
<p>Add Intent Filter to AndroidManifest.xml</p>
<p>inside&lt;activity android:name=”.MainActivity:&gt;:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">intent-filter</span> <span class="hljs-attr">android:autoVerify</span>=<span class="hljs-string">"true"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">action</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.action.VIEW"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">category</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.category.DEFAULT"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">category</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.category.BROWSABLE"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">data</span> <span class="hljs-attr">android:scheme</span>=<span class="hljs-string">"&lt;APP_NAME&gt;"</span> <span class="hljs-attr">android:host</span>=<span class="hljs-string">"mydomain.com"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">intent-filter</span>&gt;</span>
</code></pre>
<h3 id="heading-step-3-universal-links-integration">Step 3: Universal Links Integration</h3>
<p><strong>Entroll in Apple Developer Program</strong></p>
<p>You must enroll to get your Team ID and use Associated Domains.</p>
<p><strong>Enable Associated Domains in Xcode</strong></p>
<ul>
<li><p>Open your iOS project in <strong>Xcode</strong>.</p>
</li>
<li><p>Select your app target.</p>
</li>
<li><p>Go to the <strong>“Signing &amp; Capabilities”</strong> tab.</p>
</li>
<li><p>Click the <strong>“+ Capability”</strong> button.</p>
</li>
<li><p>Select <strong>“Associated Domains”</strong> from the list.</p>
</li>
<li><p>In the new <strong>“Associated Domains”</strong> section, click the <strong>+</strong> and add:</p>
</li>
</ul>
<pre><code class="lang-plaintext">applinks:mydomain.com
</code></pre>
<p>That's it! Congratulations, you have successfully created a custom deep linking implementation. Now, if you open https://mydomain.com/s/f15f8008-c9ab-49b2-a995-4c8f488df2f6, it will open directly in the app.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Implementing deep linking in a React Native app using your own domain—without relying on Firebase—gives you <strong>complete control</strong> over link behavior, branding, and user experience. By integrating <strong>Android App Links</strong> and <strong>iOS Universal Links</strong>, and properly setting up domain verification through assetlinks.json and apple-app-site-association, your app can open specific screens directly from links shared via WhatsApp, email, or anywhere else.</p>
<p>Setting up custom deep linking requires some initial backend work (like SSL, hosting .well-known files, and domain verification), but it’s a <strong>future-proof</strong> and <strong>production-ready</strong> approach that works across platforms. Once everything is set up correctly, users with your app installed will enjoy <strong>seamless navigation</strong>, and those without it will be smoothly redirected to the App Store or Play Store.</p>
<p>If you’re building a serious mobile product, choosing this method ensures your linking experience is secure, fast, and completely under your control—with <strong>no third-party dependency</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Boosting LLM Performance with RAG]]></title><description><![CDATA[What is RAG?
Retrieval-Augmented Generation. It is a technique that increases the accuracy and reliability of LLM models by feeding relevant and specific information or data sources to the model. With this system, users can build conversations with d...]]></description><link>https://blog.rohitlokhande.in/boosting-llm-performance-with-rag</link><guid isPermaLink="true">https://blog.rohitlokhande.in/boosting-llm-performance-with-rag</guid><category><![CDATA[Rag architecture]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[LLM's ]]></category><category><![CDATA[LLM-Retrieval ]]></category><category><![CDATA[rag, genai, vector-search, llmops, azure, aws, gcp]]></category><dc:creator><![CDATA[Rohit Lokhande]]></dc:creator><pubDate>Thu, 17 Apr 2025 04:18:56 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-what-is-rag">What is RAG?</h2>
<p>Retrieval-Augmented Generation. It is a technique that increases the accuracy and reliability of LLM models by feeding relevant and specific information or data sources to the model. With this system, users can build conversations with data sources. For example, a finance analyst can take assistance from this RAG system to find insights from a company report by simply questioning the system.</p>
<p>In fact, all businesses can turn their technical or policy manuals or QA sections into knowledge base resources and provide them to the LLM, by which the LLM works more efficiently for that particular domain.</p>
<p>Let’s understand RAG with one example from a business perspective. Let’s consider a real estate business. For legal documents, we are picking two scenarios—one without RAG implementation and another with RAG implementation.</p>
<p><strong>User Asked (buyer or agent):</strong> Can you explain the legal obligations of the buyer mentioned in this property sale agreement?</p>
<p><strong>Without RAG:</strong></p>
<p>If the business has not implemented RAG for this and totally depends on pre-trained data, then the model may generate a generic response or hallucinate that may not be real due to knowledge cutoff.</p>
<p><strong>With RAG:</strong></p>
<p>In this case, the chatbot is built using RAG and we feed legal documents of the property. Then the chatbot provides accurate, clause-specific answers, reduces the risk of hallucinations or generic replies, and saves time for legal professionals or buyers.</p>
<p>With this RAG-powered system, the chatbot will give a response like:</p>
<p><strong>Chatbot:</strong></p>
<p>“As per Section 4.2 of the sale agreement, the buyer is obligated to pay the remaining 90% of the property value within 30 days of signing and must complete registration within 45 days.”</p>
<h2 id="heading-how-rag-works-here"><strong>How RAG Works Here</strong></h2>
<ol>
<li><p><strong>Understanding of query:</strong></p>
<p> Here, the user query is understood by the LLM about obligation of a buyer for perticual property</p>
</li>
<li><p><strong>Retrieval of data:</strong></p>
<p> Then it fetches matching data from the provided resource knowledge from the internal database of current listings, property brochures, past chat logs or FAQs, and PDFs with rental terms.</p>
</li>
<li><p><strong>Augumented Generation:</strong></p>
<p> With the retrieved data, we can generate an accurate and conversational reply to the user by using the LLM.</p>
</li>
</ol>
<p>These are the high-level workflows of the RAG system. Now, we will further discuss how we can build a RAG system and what its components are. So, let’s start…</p>
<p>To better understand the architecture of RAG, we break it down into two parts.Before that, let’s understand how we are giving our data source—let’s suppose PDF in this case—to the LLM as context.</p>
<p>There are two options to provide context data to the LLM. First, we can directly convert the PDF to text and give it to the LLM as a system prompt context. This will work fine and also satisfy our use case, but the main issue with this approach is that the LLM has a context limit and PDFs may contain a large amount of text.</p>
<p>The other one is to break down that PDF into chunks and store its embeddings into a vector DB. At the time of a user query, we find similarity in the chunked data and only pass relevant data to the LLM.</p>
<p>Let deep dive into this…</p>
<ol>
<li><p>Injection Process:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744832591520/653f4baa-1f59-42e9-bb14-4fff13295642.png" alt class="image--center mx-auto" /></p>
<p> In this approach, we begin by collecting raw data from sources such as PDFs, Word documents, and Excel sheets. We then break this large dataset into smaller, manageable chunks. Each chunk is converted into embeddings using an appropriate embedding model and stored in a vector database. This process enables efficient retrieval of relevant or similar information based on user queries.</p>
</li>
<li><p>Querying Process:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744833945297/d6e88a18-d87f-4eca-beab-03a714cef941.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>After storing vector embeddings in a vector database, we effectively structure our knowledge base in a way that allows us to retrieve only the most relevant information based on user queries—without needing to pass large amounts of data to the LLM context.</p>
<p>Let’s take a real estate legal document example to understand this better. Suppose we’ve already processed and embedded a large collection of property legal data and stored it in a vector database. When a user submits a query like “Can you explain the legal obligations of the buyer mentioned in this property sale agreement?”—this query is also converted into an embedding using the same model that was used to process the original data. We then perform a similarity search in the vector database using the embedded query, which returns the most relevant chunks of information.</p>
<p>These relevant chunks—where the actual content of each chunk is stored in text format within the metadata—are retrieved and passed to the LLM along with the original user query as plain text context. This enables the model to generate precise and highly relevant responses based entirely on the structured knowledge we’ve provided, ensuring accuracy, efficiency, and contextual relevance.</p>
<p>This approach not only enhances the performance of the LLM but also makes the system scalable and resource-efficient for real-world applications.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>RAG (Retrieval-Augmented Generation) offers a powerful solution to overcome the limitations of traditional LLMs by combining the capabilities of retrieval systems with generative models. By integrating external knowledge sources—such as PDFs, Excel sheets, and databases—into the response-generation pipeline, RAG ensures that responses are not only accurate but also grounded in up-to-date, domain-specific data.</p>
<p>Through the use of embeddings and vector databases, RAG allows systems to intelligently fetch only the most relevant chunks of information and feed them into the LLM. This makes it possible to generate context-aware responses without overloading the model with unnecessary data.</p>
<p>Whether it’s real estate, finance, healthcare, or any other domain, RAG empowers businesses to transform static documents into dynamic knowledge bases—enabling more intelligent, reliable, and efficient interactions.</p>
<p>As AI continues to evolve, building systems with RAG will be a critical step toward developing smarter, more specialized applications that bridge the gap between raw data and meaningful insights.</p>
]]></content:encoded></item></channel></rss>