<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: zakaria chahboun</title>
    <description>The latest articles on DEV Community by zakaria chahboun (@zakariachahboun).</description>
    <link>https://dev.to/zakariachahboun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F312717%2F443768c5-9f1c-458c-8d2a-51cc11d9e968.jpg</url>
      <title>DEV Community: zakaria chahboun</title>
      <link>https://dev.to/zakariachahboun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zakariachahboun"/>
    <language>en</language>
    <item>
      <title>Gaomon Finally Released Full-Featured Linux Drivers for Their Graphic Tablets</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Mon, 19 Jan 2026 00:09:31 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/gaomon-finally-released-full-featured-linux-drivers-for-their-graphic-tablets-4e0l</link>
      <guid>https://dev.to/zakariachahboun/gaomon-finally-released-full-featured-linux-drivers-for-their-graphic-tablets-4e0l</guid>
      <description>&lt;p&gt;For years, using a graphic tablet on Linux usually meant relying on community-driven solutions or partial support. Linux users often had to choose between unofficial drivers, manual configuration, or missing features.&lt;/p&gt;

&lt;p&gt;That’s why this update from &lt;strong&gt;Gaomon&lt;/strong&gt; is worth highlighting.&lt;/p&gt;

&lt;p&gt;Gaomon has finally released &lt;strong&gt;official Linux drivers&lt;/strong&gt; for their graphic tablets — and they come with &lt;strong&gt;full functionality&lt;/strong&gt;, not just basic pen input.&lt;/p&gt;

&lt;p&gt;I recently checked Gaomon’s website (I’ve been using the &lt;strong&gt;M10K Pro&lt;/strong&gt; for years) and noticed that Linux drivers are now officially available. More importantly, they include features that are traditionally missing on Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s included
&lt;/h2&gt;

&lt;p&gt;The official Gaomon Linux drivers provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full tablet configuration support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ring Touch&lt;/strong&gt; support&lt;/li&gt;
&lt;li&gt;Easy installation process&lt;/li&gt;
&lt;li&gt;A clean and modern graphical interface&lt;/li&gt;
&lt;li&gt;Advanced customization for buttons, pressure, and tablet behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The support is not limited to a single device — &lt;strong&gt;all Gaomon tablet models&lt;/strong&gt;, including older ones, are covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  How this compares to existing Linux solutions
&lt;/h2&gt;

&lt;p&gt;Before this release, Linux users mainly depended on two well-known options:&lt;/p&gt;

&lt;h3&gt;
  
  
  DIGImend drivers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DIGImend&lt;/strong&gt; is a kernel-level open-source project that enables support for many drawing tablets on Linux. It provides solid low-level compatibility and is widely respected in the community. However, it usually lacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vendor-specific configuration tools&lt;/li&gt;
&lt;li&gt;Advanced features like ring controls&lt;/li&gt;
&lt;li&gt;Polished graphical interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DIGImend focuses on &lt;em&gt;making the hardware work&lt;/em&gt;, not on user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenTabletDriver
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;OpenTabletDriver&lt;/strong&gt; is a popular cross-platform, user-space driver with a modern UI and powerful customization options. It works well for many artists and offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extensive button and pressure configuration&lt;/li&gt;
&lt;li&gt;Profile management&lt;/li&gt;
&lt;li&gt;A clean UI across Linux, Windows, and macOS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That said, device support depends on reverse engineering, and some tablet-specific features may still be missing or incomplete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Gaomon’s official drivers matter
&lt;/h2&gt;

&lt;p&gt;Gaomon’s move brings something Linux users rarely get from hardware vendors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First-party support&lt;/li&gt;
&lt;li&gt;Full access to device-specific features&lt;/li&gt;
&lt;li&gt;No need for reverse engineering or workarounds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes Gaomon tablets a much stronger option for Linux users working in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Digital art and illustration&lt;/li&gt;
&lt;li&gt;UI/UX design&lt;/li&gt;
&lt;li&gt;Video editing&lt;/li&gt;
&lt;li&gt;Note-taking and general productivity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;p&gt;Official Gaomon Linux drivers are available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://download.gaomon.net/plus/list.php?cateId=0&amp;amp;type=Driver&amp;amp;system=linux&amp;amp;Keyword=&amp;amp;tid=9#pcb" rel="noopener noreferrer"&gt;https://download.gaomon.net/plus/list.php?cateId=0&amp;amp;type=Driver&amp;amp;system=linux&amp;amp;Keyword=&amp;amp;tid=9#pcb&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Open-source projects like &lt;strong&gt;DIGImend&lt;/strong&gt; and &lt;strong&gt;OpenTabletDriver&lt;/strong&gt; are still essential to the Linux ecosystem, and many devices continue to rely on them.&lt;/p&gt;

&lt;p&gt;But seeing a manufacturer like Gaomon ship &lt;strong&gt;fully featured, official Linux drivers&lt;/strong&gt; is a big win. Hopefully, this encourages more hardware vendors to treat Linux as a first-class platform — not an afterthought.&lt;/p&gt;

&lt;p&gt;If you’re curious about &lt;strong&gt;practical use cases for graphic tablets beyond drawing&lt;/strong&gt;, I’ve also shared a short video on my channel covering real-world workflows.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>art</category>
      <category>digitalart</category>
      <category>drawing</category>
    </item>
    <item>
      <title>Making Retype Docs AI-Ready with llms.txt Automation</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Sat, 10 Jan 2026 07:59:32 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/making-retype-docs-ai-ready-with-llmstxt-automation-50ji</link>
      <guid>https://dev.to/zakariachahboun/making-retype-docs-ai-ready-with-llmstxt-automation-50ji</guid>
      <description>&lt;p&gt;Keeping documentation up to date is one thing! helping your team or partners quickly digest changes is another. At my company, we use &lt;strong&gt;Retype&lt;/strong&gt; for our docs, and we wanted a way to make them &lt;strong&gt;instantly AI-ready&lt;/strong&gt; for summarization, search, or internal tooling.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;&lt;code&gt;retype_llms&lt;/code&gt;&lt;/strong&gt;: a lightweight GitHub Action and Python tool that generates a &lt;strong&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/strong&gt; file directly from your Markdown docs. Instead of manually exporting files or worrying about URLs and images, this tool handles it automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;llms.txt&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;If you’ve ever tried feeding docs to AI tools or building search indexes, you know the challenge: multiple Markdown files, relative images, front-matter headers, and custom routes can all break the context.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;retype_llms&lt;/code&gt; solves this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consolidating all your Markdown into a single, structured file&lt;/li&gt;
&lt;li&gt;Removing YAML front-matter that confuses AI&lt;/li&gt;
&lt;li&gt;Adding clear &lt;strong&gt;section markers&lt;/strong&gt; with file paths and URLs&lt;/li&gt;
&lt;li&gt;Resolving relative image paths to absolute URLs if needed&lt;/li&gt;
&lt;li&gt;Preserving your Retype routing logic for accurate links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means your AI tools, or even scripts that analyze your docs, get &lt;strong&gt;clean, structured, ready-to-use content&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it Fits in Your Workflow
&lt;/h2&gt;

&lt;p&gt;Whether you prefer Python scripts or GitHub Actions, &lt;code&gt;retype_llms&lt;/code&gt; fits seamlessly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python script&lt;/strong&gt;: Run locally or in CI to generate &lt;code&gt;llms.txt&lt;/code&gt; on demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Action&lt;/strong&gt;: Automatically generate &lt;code&gt;llms.txt&lt;/code&gt; on every push, optionally before Retype builds your site. The file lands in your &lt;code&gt;static/&lt;/code&gt; folder, ready to use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: Using with Retype Build Action
&lt;/h3&gt;

&lt;p&gt;You can integrate &lt;code&gt;retype_llms&lt;/code&gt; directly before your Retype build to make sure &lt;code&gt;llms.txt&lt;/code&gt; is always up to date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Retype Documentation&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate llms.txt&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zakaria-chahboun/retype_llms@v2.0.0&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Retype&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;retypeapp/action-build@latest&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to GitHub Pages&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;retypeapp/action-github-pages@latest&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;update-branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s designed to require &lt;strong&gt;zero changes to your existing Retype setup&lt;/strong&gt; 😎 just add it to your workflow, and it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Behind the Scenes
&lt;/h2&gt;

&lt;p&gt;The tool respects Retype’s logic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input detection&lt;/strong&gt;: Automatically finds the Markdown source folder from &lt;code&gt;retype.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing&lt;/strong&gt;: Generates URLs that match Retype’s &lt;code&gt;permalink&lt;/code&gt;, &lt;code&gt;route&lt;/code&gt;, and index file rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slugification&lt;/strong&gt;: Matches Retype’s lowercase-hyphen URL style&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Statistics&lt;/strong&gt;: Reports number of files, word count, and estimated tokens ✨ handy for AI integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this ensures the &lt;code&gt;llms.txt&lt;/code&gt; output mirrors your documentation structure accurately, without any manual cleanup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why You’ll Love It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fully automated: no copying or exporting files&lt;/li&gt;
&lt;li&gt;Keeps links and images intact for AI or scripts&lt;/li&gt;
&lt;li&gt;Works with GitHub Pages and existing Retype builds&lt;/li&gt;
&lt;li&gt;Lightweight and easy to set up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check it out here and give it a spin: 👉 &lt;a href="https://github.com/zakaria-chahboun/retype_llms" rel="noopener noreferrer"&gt;https://github.com/zakaria-chahboun/retype_llms&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This small addition can &lt;strong&gt;save hours of manual work&lt;/strong&gt; and make your docs &lt;strong&gt;AI-ready&lt;/strong&gt; in minutes.&lt;/p&gt;

&lt;p&gt;Happy documenting! 🚀&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>githubactions</category>
      <category>markdown</category>
      <category>devops</category>
    </item>
    <item>
      <title>Say Goodbye to WebSockets? Why SSE Might Be Your New Best Friend</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Tue, 11 Feb 2025 18:02:29 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/say-goodbye-to-websockets-why-sse-might-be-your-new-best-friend-4d7n</link>
      <guid>https://dev.to/zakariachahboun/say-goodbye-to-websockets-why-sse-might-be-your-new-best-friend-4d7n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hey fellow devs! 👋 Today, let's dive into Server-Sent Events (SSE) and explore why they might be your next favorite tool for real-time communication. If you've been relying on traditional request-response methods or wrestling with WebSocket complexity, SSE might be the simpler solution you've been looking for!&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What are Server-Sent Events?&lt;/li&gt;
&lt;li&gt;Key Benefits&lt;/li&gt;
&lt;li&gt;SSE Message Format&lt;/li&gt;
&lt;li&gt;Simple Code Examples&lt;/li&gt;
&lt;li&gt;SSE vs WebSockets&lt;/li&gt;
&lt;li&gt;Best Use Cases&lt;/li&gt;
&lt;li&gt;Pro Tips&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are Server-Sent Events?
&lt;/h2&gt;

&lt;p&gt;SSE is a standard that enables servers to push real-time updates to clients over a single HTTP connection. Think of it as a one-way communication channel where your server can send updates whenever it wants, without the client having to ask for them repeatedly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Benefits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Low Latency for Real-Time Updates
&lt;/h3&gt;

&lt;p&gt;Imagine you're building a chat app. Instead of your users constantly asking "any new messages?" (polling), the server can instantly push new messages to them.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Efficient Resource Usage
&lt;/h3&gt;

&lt;p&gt;No more polling! The server only sends data when there's actually something new to share.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Simpler than WebSockets
&lt;/h3&gt;

&lt;p&gt;While WebSockets are powerful, SSE uses standard HTTP and is much simpler to implement.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Built-in Reconnection
&lt;/h3&gt;

&lt;p&gt;Lost connection? No worries! SSE automatically handles reconnection for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSE Message Format
&lt;/h2&gt;

&lt;p&gt;Before we jump into the code, let's understand the SSE message format. The server sends messages in this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event: myevent    // Optional: name of the event
data: message     // The actual message content
id: 123          // Optional: event ID for resuming connection
retry: 10000     // Optional: reconnection time in milliseconds

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

&lt;/div&gt;



&lt;p&gt;Each field must end with a newline (&lt;code&gt;\n&lt;/code&gt;), and the message must end with two newlines (&lt;code&gt;\n\n&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Backend (Go)
&lt;/h3&gt;



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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;sseHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Set headers for SSE&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"text/event-stream"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cache-Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"no-cache"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connection"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"keep-alive"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Check if the ResponseWriter supports flushing&lt;/span&gt;
    &lt;span class="n"&gt;flusher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flusher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Streaming unsupported"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Sending events every second&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Write SSE event format&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"event:welcome&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;data: Message %d&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// Flush the response to send the event immediately&lt;/span&gt;
        &lt;span class="n"&gt;flusher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c"&gt;// Simulate a delay&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/events"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sseHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server listening on :8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;w.Header().Set("Content-Type", "text/event-stream")&lt;/code&gt;: Ensures the client treats this as an SSE connection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w.Header().Set("Cache-Control", "no-cache")&lt;/code&gt;: Prevents caching of the SSE stream.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w.Header().Set("Connection", "keep-alive")&lt;/code&gt;: Keeps the connection open for continuous&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend (JavaScript)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Basic SSE connection&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8080/events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Handle regular messages&lt;/span&gt;
&lt;span class="nx"&gt;eventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Received message:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;messages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Handle named events&lt;/span&gt;
&lt;span class="nx"&gt;eventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Handle connection open&lt;/span&gt;
&lt;span class="nx"&gt;eventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Connection opened!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Handle errors&lt;/span&gt;
&lt;span class="nx"&gt;eventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error occurred:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// To close connection when needed&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;closeConnection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;eventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SSE vs WebSockets: When to Use What? 🤹
&lt;/h2&gt;

&lt;p&gt;While both SSE and WebSockets are used for real-time communication, here’s a quick comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;SSE&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;WebSockets&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Communication&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One-way (server to client)&lt;/td&gt;
&lt;td&gt;Two-way (bi-directional)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simpler (works over HTTP)&lt;/td&gt;
&lt;td&gt;More complex (requires WebSocket protocol)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Well-supported by modern browsers&lt;/td&gt;
&lt;td&gt;Supported in most modern browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ideal for notifications, live feeds, data updates&lt;/td&gt;
&lt;td&gt;Ideal for chat, multiplayer games, full-duplex communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reconnection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic reconnection built-in&lt;/td&gt;
&lt;td&gt;Must handle reconnection manually&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Best Use Cases for SSE 🎯
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Live notifications&lt;/li&gt;
&lt;li&gt;Real-time dashboards&lt;/li&gt;
&lt;li&gt;Stock market updates&lt;/li&gt;
&lt;li&gt;Social media feeds&lt;/li&gt;
&lt;li&gt;Live sports scores&lt;/li&gt;
&lt;li&gt;System monitoring&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Pro Tips 💡
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Message Types&lt;/strong&gt;: You can send different types of events:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   // Regular message
   data: Your message here\n\n

   // Named event
   event: userconnected\n
   data: John joined\n\n

   // Multiple data lines
   data: line 1\n
   data: line 2\n\n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reconnection Control&lt;/strong&gt;: Set custom retry time:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   retry: 5000\n\n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Event IDs&lt;/strong&gt;: Track message sequence:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   id: 12345\n
   data: Your message here\n\n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Full Example&lt;/strong&gt;: All SSE Properties:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   event: notification\n
   data: Payment is successful\n
   retry: 5000\n
   id: transaction-id-12345\n\n

   event: notification\n
   data: Shipping update: Your package has been dispatched\n
   retry: 5000\n
   id: shipping-id-98765\n\n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion 🎉
&lt;/h2&gt;

&lt;p&gt;SSE is a powerful yet simple tool for real-time updates. It's perfect when you need server-to-client updates without the complexity of WebSockets. The built-in features like automatic reconnection and the simple HTTP-based protocol make it a great choice for many real-time applications.&lt;/p&gt;

&lt;p&gt;Have you used SSE in your projects? What has been your experience? Let me know in the comments below! 👇&lt;/p&gt;




&lt;p&gt;Happy coding! 🍉&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stop Fighting Go Errors: A Modern Approach to Handling Them</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Mon, 10 Feb 2025 15:21:16 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/mastering-error-handling-in-go-a-pragmatic-approach-leg</link>
      <guid>https://dev.to/zakariachahboun/mastering-error-handling-in-go-a-pragmatic-approach-leg</guid>
      <description>&lt;p&gt;Error handling is the unsung hero of robust software development. In this guide, we'll dive into a comprehensive error handling strategy that keeps your Go applications clean, informative, and maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Error Handling Strategy Overview&lt;/li&gt;
&lt;li&gt;
The Error Handling Pyramid: Where and How to Handle Errors

&lt;ul&gt;
&lt;li&gt;Utility Layer: Keep It Simple&lt;/li&gt;
&lt;li&gt;Service Layer: Add Context&lt;/li&gt;
&lt;li&gt;HTTP Handler: Log and Protect&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When to Define Custom Error Types?&lt;/li&gt;
&lt;li&gt;🏆 Conclusion &amp;amp; Rules&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Error Handling Strategy Overview
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Where?&lt;/th&gt;
&lt;th&gt;What to Do?&lt;/th&gt;
&lt;th&gt;Why?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Low-level functions (utils, DB calls, API calls, etc.)&lt;/td&gt;
&lt;td&gt;Return errors as-is (don't log)&lt;/td&gt;
&lt;td&gt;Callers higher up should decide how to handle the error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business logic (services, middle-layer functions)&lt;/td&gt;
&lt;td&gt;Wrap errors using &lt;code&gt;%w&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Adds context while preserving original error details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Handlers, CLI commands, or main()&lt;/td&gt;
&lt;td&gt;Log errors, return user-friendly messages&lt;/td&gt;
&lt;td&gt;Avoid exposing internal details to users&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Error Handling Pyramid: Where and How to Handle Errors
&lt;/h2&gt;

&lt;p&gt;Let's break down error handling across different layers of your application:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Utility Layer: Keep It Simple 🛠️
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//utils/user.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"errors"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ErrUserNotFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;FetchUserFromDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrUserNotFound&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why not wrap here?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is a utility function; wrapping it would add unnecessary details.&lt;/li&gt;
&lt;li&gt;If every function wraps errors, unwrapping becomes a nightmare.&lt;/li&gt;
&lt;li&gt;Return errors as-is. Let higher layers decide how to handle them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note 👇:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your utility function calls another function (e.g., &lt;code&gt;JSON&lt;/code&gt; parsing, &lt;code&gt;SQL&lt;/code&gt; query execution) that returns an error, you generally still want to return the error &lt;u&gt;as-is&lt;/u&gt; in the utility layer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Service Layer: Add Context 🔍
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// service/user.go&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetUserProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FetchUserFromDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Wrap the error with context while preserving the original error 😉&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to get user profile: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why wrap here?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adds context (e.g., "failed to get user profile").&lt;/li&gt;
&lt;li&gt;Maintains stack trace for better debugging.&lt;/li&gt;
&lt;li&gt;If multiple functions call &lt;code&gt;FetchUserFromDB&lt;/code&gt;, each can add its own context.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. HTTP Handler: Log and Protect 🛡️
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// handlers/user.go&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewJSONHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;UserHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUserProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Catch our specific error because we already know it 😎&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrUserNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"User not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// Log unexpected errors with additional context for debugging&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to process user request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"userID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// Return a generic internal server error for unknown issues&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Internal Server Error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why log here instead of inside &lt;code&gt;GetUserProfile&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The handler is responsible for logging.&lt;/li&gt;
&lt;li&gt;We unwrap and check errors for specific cases (&lt;code&gt;ErrUserNotFound&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Users see a friendly message instead of raw error details.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. When to Define Custom Error Types?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use sentinel errors (&lt;code&gt;var ErrX = errors.New()&lt;/code&gt;) when errors have clear meaning (e.g., "user not found").&lt;/li&gt;
&lt;li&gt;Use custom error types when errors have extra fields (e.g., HTTP status codes, detailed error codes).
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ErrUnauthorized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Unauthorized"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now will use it in our handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Simulation for authentication&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ErrUnauthorized&lt;/span&gt; &lt;span class="c"&gt;// Simulated error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Magic here 🤠 👇&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;httpErr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;httpErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// If err is of type *HTTPError, extract it and use its status code and message&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;httpErr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;httpErr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// If error is unknown, return a generic 500 Internal Server Error&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Internal Server Error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hint 💡:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using &lt;code&gt;errors.As&lt;/code&gt;:&lt;br&gt;
Inside the handler function, the &lt;code&gt;errors.As(err, &amp;amp;httpErr)&lt;/code&gt; is used to check if the error &lt;code&gt;err&lt;/code&gt; (in this case, &lt;code&gt;ErrUnauthorized&lt;/code&gt;) is of type &lt;code&gt;*HTTPError&lt;/code&gt;. The &lt;code&gt;errors.As&lt;/code&gt; function performs a type assertion and, if the error matches the target type (&lt;code&gt;*HTTPError&lt;/code&gt;), it &lt;u&gt;assigns the value&lt;/u&gt; to the &lt;code&gt;httpErr&lt;/code&gt; variable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🏆 Conclusion &amp;amp; Rules
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;🚫 Don't log in low-level functions&lt;/li&gt;
&lt;li&gt;🧩 Wrap errors in business logic for context&lt;/li&gt;
&lt;li&gt;🌟 Log at HTTP/CLI level&lt;/li&gt;
&lt;li&gt;🕵️ Use &lt;code&gt;errors.Is()&lt;/code&gt; for known errors&lt;/li&gt;
&lt;li&gt;🧸 Use &lt;code&gt;errors.As()&lt;/code&gt; for custom error types&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Happy coding! 🍉&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>softwareengineering</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Go Context — TODO() vs Background() No more confusing!</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Mon, 09 Sep 2024 16:02:03 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/are-you-confused-about-contexttodo-vs-contextbackground-heres-what-you-need-to-know-2h46</link>
      <guid>https://dev.to/zakariachahboun/are-you-confused-about-contexttodo-vs-contextbackground-heres-what-you-need-to-know-2h46</guid>
      <description>&lt;p&gt;In Go, the &lt;code&gt;context&lt;/code&gt; package helps manage request-scoped values, cancellation signals, and deadlines. &lt;br&gt;
 Two common ways to start a context are &lt;code&gt;context.TODO()&lt;/code&gt; and &lt;code&gt;context.Background()&lt;/code&gt;. &lt;br&gt;
 Though they behave similarly, they serve different purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  context.Background()
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;context.Background()&lt;/code&gt; is the default when you don’t need any special handling (like cancellation or deadlines). &lt;br&gt;
 It's often used in &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;init&lt;/code&gt;, or when initializing operations that don't need a more specific context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
     &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Addr&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BaseContext&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;
     &lt;span class="p"&gt;}}&lt;/span&gt;
     &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;context.Background()&lt;/code&gt; is used to establish a base context for the HTTP server.&lt;/p&gt;

&lt;h2&gt;
  
  
  context.TODO()
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;context.TODO()&lt;/code&gt; is a placeholder context. Use it when you're unsure of what context to provide or when planning to refactor later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Placeholder, decision on context pending&lt;/span&gt;
     &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SaveOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orderData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to save order:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;context.TODO()&lt;/code&gt; is temporarily used for a database operation until a more specific context is defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Differences
&lt;/h2&gt;

&lt;p&gt;Both functions return an empty context, but they express different intentions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context.Background()&lt;/code&gt;&lt;/strong&gt;: Used when you're confident no special context features are needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context.TODO()&lt;/code&gt;&lt;/strong&gt;: A temporary placeholder context, signaling future changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When to Use &lt;code&gt;context.Background()&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When initializing core services like HTTP servers or database connections.&lt;/li&gt;
&lt;li&gt;When there's no need for cancellation, deadlines, or values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When to Use &lt;code&gt;context.TODO()&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When refactoring, and you haven’t decided on the context yet.&lt;/li&gt;
&lt;li&gt;When implementing early-stage code that requires future improvements.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>development</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using defer in Go: Best Practices and Common Use Cases</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Mon, 19 Aug 2024 15:11:53 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/common-use-cases-for-defer-in-go-1071</link>
      <guid>https://dev.to/zakariachahboun/common-use-cases-for-defer-in-go-1071</guid>
      <description>&lt;p&gt;In Go, the defer keyword is a powerful tool that helps manage resources and ensure that cleanup actions are performed when a function exits. The deferred functions are executed when the surrounding function returns, whether it returns normally, due to an error, or because of a panic. This ensures that cleanup code runs regardless of how the function exits, making resource management simpler and more reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Points about defer:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Execution Timing: Deferred functions are executed in LIFO (Last In, First Out) order when the surrounding function returns, either by completing its execution, encountering a return statement, or due to a panic.&lt;/li&gt;
&lt;li&gt;Resource Management: It helps in automatically closing resources like files and network connections, unlocking mutexes, and performing other cleanup tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1. Order of Multiple Defer Statements&lt;/li&gt;
&lt;li&gt;2. Resource Cleanup&lt;/li&gt;
&lt;li&gt;3. Unlocking Mutexes&lt;/li&gt;
&lt;li&gt;4. Releasing Database Connections&lt;/li&gt;
&lt;li&gt;5. Restoring State&lt;/li&gt;
&lt;li&gt;6. Handling Panics&lt;/li&gt;
&lt;li&gt;7. Logging and Timing&lt;/li&gt;
&lt;li&gt;8. Flushing Buffers&lt;/li&gt;
&lt;li&gt;9. Handling HTTP Request Bodies&lt;/li&gt;
&lt;li&gt;10. Risk of Closing a Failed Opening Without defer&lt;/li&gt;
&lt;li&gt;11. Risk of Using defer Before Checking if a File Was Opened&lt;/li&gt;
&lt;li&gt;12. Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Order of Multiple Defer Statements &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In Go, multiple defer statements within a function are executed in &lt;strong&gt;reverse&lt;/strong&gt; order of their appearance. This is useful for managing multiple cleanup tasks, ensuring they are performed in a specific order when the function exits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkc6c072lrox65hnriui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkc6c072lrox65hnriui.png" alt="stack of books" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;exampleFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Start of function"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"First defer: executed last"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Second defer: executed second"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Third defer: executed first"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"End of function"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start of function
End of function
Third defer: executed first
Second defer: executed second
First defer: executed last
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Resource Cleanup &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most common uses of &lt;code&gt;defer&lt;/code&gt; is to ensure that resources like files are properly closed after they are no longer needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="c"&gt;// Return the error if opening the file fails&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Ensure the file is closed when the function exits&lt;/span&gt;

    &lt;span class="c"&gt;// Process the file...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;os.File&lt;/code&gt; implements &lt;code&gt;io.ReadCloser&lt;/code&gt;, so using &lt;code&gt;defer&lt;/code&gt; here ensures that the file is closed properly, preventing resource leaks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Unlocking Mutexes &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;When working with concurrency, it’s crucial to release locks to prevent deadlocks. &lt;code&gt;defer&lt;/code&gt; helps manage mutexes effectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mu&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;criticalSection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Ensure the mutex is unlocked when the function exits&lt;/span&gt;

    &lt;span class="c"&gt;// Critical section...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By deferring &lt;code&gt;mu.Unlock()&lt;/code&gt;, you ensure that the &lt;code&gt;mutex&lt;/code&gt; is always released, making the code easier to understand and less error-prone.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Releasing Database Connections &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Database connections should be closed when they are no longer needed to free up resources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;queryDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"driver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"database=example"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Ensure the database connection is closed when the function exits&lt;/span&gt;

    &lt;span class="c"&gt;// Query the database...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Restoring State &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Example: Changing and Restoring Working Directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When changing the working directory, it’s important to restore it to its original state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;changeDirectory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;oldDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getwd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tmp"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Restore the working directory when the function exits&lt;/span&gt;

    &lt;span class="c"&gt;// Work in /tmp...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;defer&lt;/code&gt; makes it easy to restore the original directory automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Handling Panics &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Example: Recovering from Panics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;defer&lt;/code&gt; can be used to recover from panics and handle errors gracefully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;safeFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recovered from panic:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;
    &lt;span class="c"&gt;// Code that might panic...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By deferring a function that handles panics, you can ensure that your application remains robust even in the face of unexpected errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Logging and Timing &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Example: Timing Function Execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;defer&lt;/code&gt; is useful for measuring execution time or logging when a function exits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;measureTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Execution time: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="c"&gt;// Code to measure...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach simplifies timing code and ensures that the duration is logged when the function completes.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Flushing Buffers &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Example: Flushing Buffered I/O&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Buffered I/O operations should be flushed to ensure that all data is written out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;bufferedWrite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Ensure the buffer is flushed when the function exits&lt;/span&gt;

    &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;defer&lt;/code&gt; here guarantees that any buffered data is written out before the function completes.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Handling HTTP Request Bodies &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Example: Closing HTTP Request Body&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTTP request bodies implement &lt;code&gt;io.ReadCloser&lt;/code&gt;, so it’s crucial to close them after use to free up resources and avoid leaks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Ensure that the request body is closed when the function exits&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error closing request body:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Process the body...&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Request body:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By deferring the &lt;code&gt;req.Body.Close()&lt;/code&gt;, you ensure that the body is closed properly, even if an error occurs while reading or processing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Risk of Closing a Failed Opening Without defer &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;When you open a file or other resource in Go, it’s crucial to ensure that the resource is properly closed once it’s no longer needed. However, if you attempt to close a resource after error checking without using &lt;code&gt;defer&lt;/code&gt;, you could introduce risks into your code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example Without defer
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="c"&gt;// Handle error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// Risk: If something goes wrong before this point, the file might never be closed&lt;/span&gt;
&lt;span class="c"&gt;// Additional operations here...&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Attempt to close the file later&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not using &lt;code&gt;defer&lt;/code&gt; to close resources in Go can lead to unintended consequences, such as attempting to close a resource that was never successfully opened, resulting in unexpected behavior or panics. Additionally, if an error occurs before the explicit &lt;code&gt;Close()&lt;/code&gt; call, the resource might remain open, causing leaks and exhausting system resources. As the code becomes more complex, ensuring all resources are properly closed becomes increasingly difficult, raising the likelihood of overlooking a close operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Risk of Using &lt;code&gt;defer&lt;/code&gt; Before Checking if a File Was Opened &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In Go, it's crucial to place a &lt;code&gt;defer&lt;/code&gt; statement after verifying that a resource, like a file, was successfully opened.&lt;br&gt;
Placing &lt;code&gt;defer&lt;/code&gt; before the error check can introduce several risks and undesirable behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of Incorrect Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Incorrect: This should be deferred after the error check&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="c"&gt;// Handle error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// Additional operations here...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Placing defer &lt;code&gt;file.Close()&lt;/code&gt; before checking if &lt;code&gt;os.Open&lt;/code&gt; succeeded can cause several issues. If the file wasn't opened and is nil, attempting to close it will lead to a runtime panic since Go executes all deferred functions even when an error occurs. This approach also makes the code misleading, implying that the file was successfully opened when it might not have been, which complicates understanding and maintenance. Furthermore, if a panic does occur, debugging becomes more challenging, especially in complex codebases, as tracing the issue back to the misplaced defer can take additional effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Conclusion &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The defer keyword in Go simplifies resource management and enhances code clarity by ensuring that cleanup actions are performed automatically when a function exits. By using defer in these common scenarios, you can write more robust, maintainable, and error-free code.&lt;/p&gt;

</description>
      <category>go</category>
      <category>developer</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Comprehensive Guide to Type Casting and Conversions in Go</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Sun, 18 Aug 2024 01:20:21 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/a-comprehensive-guide-to-type-casting-and-conversions-in-go-26di</link>
      <guid>https://dev.to/zakariachahboun/a-comprehensive-guide-to-type-casting-and-conversions-in-go-26di</guid>
      <description>&lt;p&gt;Go, also known as Golang, is a statically typed language. This means that the type of every variable is known at compile time, providing safety and predictability in your code. However, this also requires that any conversion from one type to another is explicit and deliberate. In this article, we’ll explore the various type casting and conversion mechanisms available in Go, from basic numeric conversions to more complex interface and pointer conversions.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Basic Type Conversions
&lt;/h2&gt;

&lt;p&gt;Go allows conversion between basic types like integers, floating-point numbers, and strings, but these conversions must be done explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Numeric Types
&lt;/h3&gt;

&lt;p&gt;Conversions between different numeric types are straightforward but must be explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// int to float64&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c"&gt;// int to uint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we convert an int to a &lt;code&gt;float64&lt;/code&gt; and to a &lt;code&gt;uint&lt;/code&gt;. These conversions are explicit because Go does not perform automatic (implicit) type conversions.&lt;/p&gt;

&lt;h3&gt;
  
  
  String and Byte Slice
&lt;/h3&gt;

&lt;p&gt;Go strings are immutable, but they can be converted to and from byte slices (&lt;code&gt;[]byte&lt;/code&gt;), which are mutable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;// string to []byte&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// []byte to string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, you can convert between strings and rune slices (&lt;code&gt;[]rune&lt;/code&gt;), where rune is a type alias for &lt;code&gt;int32&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;rune&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;rune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;// string to []rune&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// []rune to string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Custom Type Conversions
&lt;/h2&gt;

&lt;p&gt;In Go, you can define your own types based on existing ones. Conversions between custom types and their underlying types are explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;MyInt&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mi&lt;/span&gt; &lt;span class="n"&gt;MyInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;// int to MyInt&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i2&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c"&gt;// MyInt to int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This explicit conversion is necessary to ensure that the compiler can verify the safety of your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Pointer Conversions
&lt;/h2&gt;

&lt;p&gt;Pointers in Go reference the memory address of a variable. You can convert between a value and its pointer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;     &lt;span class="c"&gt;// int to *int (pointer to int)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;      &lt;span class="c"&gt;// *int to int (dereferencing)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Interface Type Conversions
&lt;/h2&gt;

&lt;p&gt;Interfaces in Go are used to define a set of methods. You can convert between concrete types and interfaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;    &lt;span class="c"&gt;// int to interface{}&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c"&gt;// interface{} to int (type assertion)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type Assertions
&lt;/h3&gt;

&lt;p&gt;A type assertion provides access to an interface's concrete value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a is an int:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type Switch
&lt;/h3&gt;

&lt;p&gt;A type switch allows you to perform different actions based on the dynamic type of an interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a is an int:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a is a string:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a is of unknown type"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Unsafe Conversions
&lt;/h2&gt;

&lt;p&gt;The unsafe package allows you to bypass Go’s type safety, enabling conversions that would otherwise be illegal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"unsafe"&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c"&gt;// *int to *float64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Warning: Unsafe conversions should be used sparingly and only when absolutely necessary, as they can lead to undefined behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. Channel Type Conversions
&lt;/h2&gt;

&lt;p&gt;Channels are a powerful feature in Go, allowing communication between goroutines. You can convert between bidirectional and unidirectional channels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sendOnlyChan&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;  &lt;span class="c"&gt;// bidirectional to send-only&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;recvOnlyChan&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;  &lt;span class="c"&gt;// bidirectional to receive-only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Struct and Array Conversions
&lt;/h2&gt;

&lt;p&gt;Conversions between structs or arrays with identical layouts require explicit casting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Coord&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// Convert Point to Coord (same field types)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Slice Conversions
&lt;/h2&gt;

&lt;p&gt;Slices are references to arrays, and while you can convert between slices of the same type, converting between different types of slices requires an explicit conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c"&gt;// Convert a slice to another slice of the same type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Nil Interface Conversions
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;nil&lt;/code&gt; value in Go can be assigned to any &lt;code&gt;interface&lt;/code&gt; type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Function Type Conversions
&lt;/h2&gt;

&lt;p&gt;Go functions can be converted to different types, provided the signatures are compatible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FuncType&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;FuncType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FuncType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// Convert function to FuncType&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11. Array-to-Slice Conversion
&lt;/h2&gt;

&lt;p&gt;You can create a slice from an array, which is essentially a reference to the array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sl&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c"&gt;// Convert array to slice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Type casting and conversions in Go are explicit by design, making the code safer and easier to understand. By requiring explicit conversions, Go helps prevent subtle bugs that can arise from implicit type coercion, common in some other programming languages. Understanding these conversions and using them correctly is crucial for writing robust and efficient Go programs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>backend</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Supabase, Self-hosting with Podman Instead of Docker!</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Fri, 23 Sep 2022 07:03:14 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/supabase-self-hosting-with-podman-1mhl</link>
      <guid>https://dev.to/zakariachahboun/supabase-self-hosting-with-podman-1mhl</guid>
      <description>&lt;h3&gt;
  
  
  Supabase, Self-hosting with Podman!
&lt;/h3&gt;

&lt;p&gt;Supabase is an open source Firebase alternative providing all the backend features you need to build a product. You can use it completely, or just the features you need. Start a project with the &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;hosted&lt;/a&gt; platform or learn how to host Supabase yourself with podman 👇.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install requirements
&lt;/h3&gt;

&lt;p&gt;You need to install &lt;code&gt;podman&lt;/code&gt;, &lt;code&gt;podman-docker&lt;/code&gt; and &lt;code&gt;docker-compose&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;i'm using linux pop_os&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;podman podman-docker docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;in your ~./bashrc file add docker as a podman alias (alias docker=podman)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now. You have to clone the supabase repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 https://github.com/supabase/supabase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Go to the docker folder&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;supabase/docker

&lt;span class="c"&gt;# Copy the fake env vars&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now. You have to configure docker hub mirror in &lt;em&gt;/etc/containers/registries.conf&lt;/em&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/containers/registries.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add these lines to the end of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;unqualified-search-registries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'docker.io'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[[registry]]&lt;/span&gt;
&lt;span class="py"&gt;prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docker.io"&lt;/span&gt;
&lt;span class="py"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docker.io"&lt;/span&gt;

&lt;span class="nn"&gt;[[registry.mirror]]&lt;/span&gt;
&lt;span class="py"&gt;prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docker.io"&lt;/span&gt;
&lt;span class="py"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docker.mirrors.ustc.edu.cn"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it! Now. You are ready to install supabase studio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally. visit &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; to start using Supabase Studio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lq7eds8gs320730lhzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lq7eds8gs320730lhzn.png" alt="local supabase dashboard" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you face this error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ERROR: for db  error preparing container 22e6838a1fd10267d63f69ef400000a84a1a857a5e46718003f8a5f63388bb0f for attach: cannot listen on the TCP port: listen tcp4 :5432: bind: address already in use&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just change the &lt;code&gt;POSTGRES_PORT&lt;/code&gt; in &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;😊 Enjoy!&lt;br&gt;
🐦 &lt;a href="https://twitter.com/zaki_chahboun" rel="noopener noreferrer"&gt;My Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>supabase</category>
      <category>firebase</category>
      <category>docker</category>
      <category>podman</category>
    </item>
    <item>
      <title>Sapper(svelte) + CodyFrame Ui</title>
      <dc:creator>zakaria chahboun</dc:creator>
      <pubDate>Sun, 07 Jun 2020 21:58:11 +0000</pubDate>
      <link>https://dev.to/zakariachahboun/sapper-svelte-codyframe-ui-31e</link>
      <guid>https://dev.to/zakariachahboun/sapper-svelte-codyframe-ui-31e</guid>
      <description>&lt;h2&gt;
  
  
  Sapper + Codyframe
&lt;/h2&gt;

&lt;p&gt;This project is a template for Sapper if you want to work with CodyFrame framework UI (&lt;a href="https://codyhouse.co/ds/docs/framework" rel="noopener noreferrer"&gt;From Cody House&lt;/a&gt;), And you want to compile the &lt;strong&gt;SASS files&lt;/strong&gt; and using it directly with &lt;strong&gt;Rollup&lt;/strong&gt; 👌&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Note: You can clone this &lt;a href="https://github.com/zakaria-chahboun/sapper-codyframe" rel="noopener noreferrer"&gt;template&lt;/a&gt; directly or you can follow the instructions below 🍵&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  First things 🤚
&lt;/h3&gt;

&lt;p&gt;After getting the template of &lt;a href="https://sapper.svelte.dev/" rel="noopener noreferrer"&gt;sapper&lt;/a&gt; for Rollup by:&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;npx degit "sveltejs/sapper-template#rollup" my-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You have to install the ordinary dependencies by:&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And try to run it &lt;em&gt;(on &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;)&lt;/em&gt; by:&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Issues could happen 📛
&lt;/h3&gt;

&lt;p&gt;If you have this issue:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/sveltejs/sapper/issues/1257" rel="noopener noreferrer"&gt;UnhandledPromiseRejectionWarning: Error: No valid exports main found for /..node_modules/@rollup/pluginutils&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just remove the &lt;code&gt;rollup&lt;/code&gt; package from npm and reinstall a new version of it like &lt;em&gt;"2.13.0"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Also if you don't have &lt;strong&gt;Polka&lt;/strong&gt; install it by:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save polka&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can use &lt;strong&gt;express js&lt;/strong&gt; 🌱 instead of &lt;em&gt;Polka&lt;/em&gt;, learn how to do that from this &lt;a href="https://youtu.be/kiou6WVYswM" rel="noopener noreferrer"&gt;Youtube video&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies for SASS compiler 🏵️
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;svelte-preprocess 👈&lt;/li&gt;
&lt;li&gt;autoprefixer 👈&lt;/li&gt;
&lt;li&gt;node-sass 👈&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;npm install -D node-sass autoprefixer svelte-preprocess&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add -D node-sass autoprefixer svelte-preprocess&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rollup Configurations 🦊
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F01.png" width="583" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the &lt;strong&gt;rollup.config.js&lt;/strong&gt; file, add these lines outside of &lt;em&gt;export default&lt;/em&gt; to be accessible globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// for sass (codyframe)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sveltePreprocess&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte-preprocess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sveltePreprocess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;scss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;includePaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;postcss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autoprefixer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also add these lines in both 🤠 &lt;strong&gt;&lt;em&gt;Client and Server&lt;/em&gt;&lt;/strong&gt; sections inside of &lt;strong&gt;svelte({...})&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;svelte&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="nx"&gt;preprocess&lt;/span&gt; &lt;span class="c1"&gt;// Add this line&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get the CodyFrame 🤦‍♂
&lt;/h3&gt;

&lt;p&gt;Clone the official project from GitHub: &lt;a href="https://github.com/CodyHouse/codyhouse-framework" rel="noopener noreferrer"&gt;Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We just want the &lt;strong&gt;assets&lt;/strong&gt; folder 🙄, So copy it inside &lt;strong&gt;&lt;em&gt;codyframe&lt;/em&gt;&lt;/strong&gt; folder in your &lt;strong&gt;&lt;em&gt;src&lt;/em&gt;&lt;/strong&gt; folder &lt;em&gt;(src/codyframe)&lt;/em&gt; .&lt;/p&gt;

&lt;p&gt;We want the &lt;em&gt;style.scss&lt;/em&gt; and &lt;em&gt;util.js&lt;/em&gt; later 👌.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F02.png" width="586" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sapper Tepmlate File 🍪
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F03.png" width="580" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the top of &lt;em&gt;template.html&lt;/em&gt; file in the &lt;em&gt;src&lt;/em&gt; folder, We have to add a &lt;code&gt;class="js"&lt;/code&gt; attribute to the &lt;code&gt;&amp;lt;html ..&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sapper Layout File 🐧
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F04.png" width="587" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;_layout.svelte&lt;/strong&gt; file inside of &lt;em&gt;routes&lt;/em&gt; folder, We want to be sure that codyframe script run after the DOM is loaded 👧, So for that we have to use &lt;code&gt;onMount&lt;/code&gt; from svelte just like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onMount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;codyFrameScripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;onMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ---- To mount the CodyFrame scripts ----&lt;/span&gt;
    &lt;span class="nx"&gt;codyFrameScripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;codyframe/util.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can now add the javascript libraries to the head tag like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--  cody framework - js libraries --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;svelte:head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;defer&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;{codyFrameScripts}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svelte:head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And of course we have also to import the scss style 🌻!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Codyframework Global Scss --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"scss"&lt;/span&gt; &lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"./codyframe/assets/css/style.scss"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Last Step! 🤗
&lt;/h3&gt;

&lt;p&gt;Don't forget to add &lt;strong&gt;&lt;em&gt;util.js&lt;/em&gt;&lt;/strong&gt; inside of &lt;code&gt;codyframe&lt;/code&gt; folder in the &lt;strong&gt;static&lt;/strong&gt; folder of your project 👈.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2Fsapper-codyframe%2Fmaster%2Fexplanation%2F05.png" width="587" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing! 👍
&lt;/h3&gt;

&lt;p&gt;In your &lt;em&gt;&lt;code&gt;index.svelte&lt;/code&gt;&lt;/em&gt; route, Add any code to test codyframe components, Like this Button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn--primary btn--md"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Zaki Button!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One more thing! 👎
&lt;/h3&gt;

&lt;p&gt;The codyhouse doesn't have components for modern JavaScript frameworks like &lt;em&gt;Svelte/Vue/React ..&lt;/em&gt;, And also his bad JavaScript functionality run one time when the page is loaded 🤦‍♂&lt;/p&gt;

&lt;p&gt;So you'll get a lot of troubles when you work with a SPA project (Single Page Application), But there is a solution out of the box from sapper 💕&lt;/p&gt;

&lt;p&gt;Each time you have to switch to another route, You have to be sure that the link (for example) &lt;code&gt;&amp;lt;a href="/profile"&amp;gt;&lt;/code&gt; has a &lt;code&gt;rel="external"&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"external"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/profile"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Enjoy! You can buy me a &lt;a href="https://paypal.me/zakariachahboun" rel="noopener noreferrer"&gt;coffee 🐿&lt;/a&gt; 💕
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2FZakiQtProjects%2Fmaster%2FIMAGE2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzakaria-chahboun%2FZakiQtProjects%2Fmaster%2FIMAGE2.png" width="200" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>sapper</category>
      <category>svelte</category>
      <category>css</category>
    </item>
  </channel>
</rss>
