<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Go on Nalar</title>
    <link>https://nalar.dev/tags/go/</link>
    <description>Recent content in Go on Nalar</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 02 Sep 2026 00:00:00 +0700</lastBuildDate>
    <atom:link href="https://nalar.dev/tags/go/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Reading Streams Correctly in Go with io.Reader</title>
      <link>https://nalar.dev/reading-streams-correctly-in-go-with-io-reader/</link>
      <pubDate>Wed, 02 Sep 2026 00:00:00 +0700</pubDate>
      <guid>https://nalar.dev/reading-streams-correctly-in-go-with-io-reader/</guid>
      <description>&lt;p&gt;Go&amp;rsquo;s &lt;code&gt;io.Reader&lt;/code&gt; interface is tiny:&lt;/p&gt;&#xA;&lt;div&#xA;  x-data=&#34;{ code: $el.querySelector(&#39;code&#39;).innerText, copied: false }&#34;&#xA;  class=&#34;code-block group relative my-6 overflow-hidden rounded-xl border border-line bg-surface-muted dark:border-night-line dark:bg-night-surface&#34;&gt;&#xA;  &lt;button&#xA;    type=&#34;button&#34;&#xA;    @click=&#34;navigator.clipboard.writeText(code); copied = true; setTimeout(() =&gt; copied = false, 1600)&#34;&#xA;    class=&#34;absolute right-3 top-3 z-10 rounded-lg border border-line-strong bg-surface px-2 py-1 font-mono text-[0.65rem] text-muted opacity-0 transition group-hover:opacity-100 hover:bg-ink hover:text-white dark:border-night-line dark:bg-night dark:text-night-muted dark:hover:bg-white dark:hover:text-ink&#34;&gt;&#xA;    &lt;span x-text=&#34;copied ? &#39;Copied&#39; : &#39;Copy&#39;&#34;&gt;&lt;/span&gt;&#xA;  &lt;/button&gt;&#xA;  &#xA;  &lt;div class=&#34;overflow-x-auto p-4 text-sm leading-6 [&amp;_pre]:!m-0 [&amp;_pre]:!bg-transparent [&amp;_pre]:!p-0 [&amp;_code]:font-mono&#34;&gt;&#xA;    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;type&lt;/span&gt; Reader &lt;span style=&#34;font-weight:bold&#34;&gt;interface&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Read(p []&lt;span style=&#34;&#34;&gt;byte&lt;/span&gt;) (n &lt;span style=&#34;&#34;&gt;int&lt;/span&gt;, err &lt;span style=&#34;&#34;&gt;error&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;  &lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;Its small surface hides an important contract: a read is allowed to return fewer bytes than the buffer can hold, and it can return useful bytes together with an error. Correct stream processing must handle both cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Short Reads and Exact-Length I/O in Go</title>
      <link>https://nalar.dev/short-reads-and-exact-length-io-in-go/</link>
      <pubDate>Wed, 02 Sep 2026 00:00:00 +0700</pubDate>
      <guid>https://nalar.dev/short-reads-and-exact-length-io-in-go/</guid>
      <description>&lt;p&gt;Reading bytes in Go looks simple: allocate a buffer, call &lt;code&gt;Read&lt;/code&gt;, and inspect the error. The subtlety is that &lt;code&gt;io.Reader&lt;/code&gt; does not promise to fill the buffer in one call. A valid reader may return fewer bytes than requested even when more data will arrive later.&lt;/p&gt;&#xA;&lt;p&gt;That behavior matters for network protocols, binary file formats, framed messages, and any code that expects an exact number of bytes. Correct stream handling starts by matching the API to the requirement: use ordinary &lt;code&gt;Read&lt;/code&gt; when partial progress is acceptable, and use helpers such as &lt;code&gt;io.ReadFull&lt;/code&gt; when a fixed-size field must be complete.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Preserve Cancellation Causes with context.WithCancelCause in Go</title>
      <link>https://nalar.dev/go-context-cancellation-causes/</link>
      <pubDate>Tue, 01 Sep 2026 00:00:00 +0700</pubDate>
      <guid>https://nalar.dev/go-context-cancellation-causes/</guid>
      <description>&lt;p&gt;Go&amp;rsquo;s &lt;code&gt;context.Context&lt;/code&gt; propagates deadlines and cancellation across API boundaries. Traditional cancellation tells downstream work that it should stop, but &lt;code&gt;ctx.Err()&lt;/code&gt; only reports &lt;code&gt;context.Canceled&lt;/code&gt; or &lt;code&gt;context.DeadlineExceeded&lt;/code&gt;. Sometimes the reason matters.&lt;/p&gt;&#xA;&lt;p&gt;Go 1.20 introduced &lt;code&gt;context.WithCancelCause&lt;/code&gt;, and later releases added cause-aware deadline helpers. They preserve a domain error without changing normal cancellation behavior.&lt;/p&gt;&#xA;&lt;h2 id=&#34;attach-a-cause-to-cancellation&#34;&gt;Attach a cause to cancellation&lt;/h2&gt;&#xA;&lt;div&#xA;  x-data=&#34;{ code: $el.querySelector(&#39;code&#39;).innerText, copied: false }&#34;&#xA;  class=&#34;code-block group relative my-6 overflow-hidden rounded-xl border border-line bg-surface-muted dark:border-night-line dark:bg-night-surface&#34;&gt;&#xA;  &lt;button&#xA;    type=&#34;button&#34;&#xA;    @click=&#34;navigator.clipboard.writeText(code); copied = true; setTimeout(() =&gt; copied = false, 1600)&#34;&#xA;    class=&#34;absolute right-3 top-3 z-10 rounded-lg border border-line-strong bg-surface px-2 py-1 font-mono text-[0.65rem] text-muted opacity-0 transition group-hover:opacity-100 hover:bg-ink hover:text-white dark:border-night-line dark:bg-night dark:text-night-muted dark:hover:bg-white dark:hover:text-ink&#34;&gt;&#xA;    &lt;span x-text=&#34;copied ? &#39;Copied&#39; : &#39;Copy&#39;&#34;&gt;&lt;/span&gt;&#xA;  &lt;/button&gt;&#xA;  &#xA;  &lt;div class=&#34;overflow-x-auto p-4 text-sm leading-6 [&amp;_pre]:!m-0 [&amp;_pre]:!bg-transparent [&amp;_pre]:!p-0 [&amp;_code]:font-mono&#34;&gt;&#xA;    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;package&lt;/span&gt; main&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;import&lt;/span&gt; (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;errors&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;var&lt;/span&gt; ErrSuperseded = errors.New(&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;request superseded&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;func&lt;/span&gt; main() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ctx, cancel := context.WithCancelCause(context.Background())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cancel(ErrSuperseded)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fmt.Println(ctx.Err())           &lt;span style=&#34;font-style:italic&#34;&gt;// context canceled&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fmt.Println(context.Cause(ctx)) &lt;span style=&#34;font-style:italic&#34;&gt;// request superseded&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;  &lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;Code that only understands &lt;code&gt;Context&lt;/code&gt; still sees ordinary cancellation. Code that needs diagnostic detail can call &lt;code&gt;context.Cause&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
