<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Modern Go on</title><link>/tags/modern-go/</link><description>Recent content in Modern Go on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 02 Mar 2025 00:00:00 +0000</lastBuildDate><atom:link href="/tags/modern-go/index.xml" rel="self" type="application/rss+xml"/><item><title>Lesson 5: What's New in Go 1.25–1.26 — Swiss table maps, weak pointers, and the future</title><link>/post/go/go-modern-latest/</link><pubDate>Sun, 02 Mar 2025 00:00:00 +0000</pubDate><guid>/post/go/go-modern-latest/</guid><description>&lt;p&gt;Every major Go release follows a rhythm: one or two headline language features, a handful of standard library additions, and a runtime improvement you probably do not notice directly but that makes your services run better in aggregate. Go 1.23 and 1.24 brought the iterator protocol, &lt;code&gt;go tool&lt;/code&gt; improvements, and the &lt;code&gt;unique&lt;/code&gt; package. Go 1.25 and 1.26 continued this pattern with Swiss table map internals, a production-ready weak pointer API, and improvements to the toolchain that affect how you build, ship, and profile Go binaries.&lt;/p&gt;</description></item><item><title>Lesson 4: Structured Logging with slog — The stdlib logger Go always needed</title><link>/post/go/go-modern-slog/</link><pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate><guid>/post/go/go-modern-slog/</guid><description>&lt;p&gt;I have switched logging libraries in Go more times than I care to admit. Started with the standard &lt;code&gt;log&lt;/code&gt; package — fine for scripts, useless in production because you cannot query plain text logs efficiently. Moved to &lt;code&gt;logrus&lt;/code&gt; because everyone was using it. Switched to &lt;code&gt;zap&lt;/code&gt; when I needed better performance. Considered &lt;code&gt;zerolog&lt;/code&gt; when I wanted allocation-free hot paths. Each migration meant updating every file that imported the old library, convincing teammates, and writing bridge adapters for third-party code that used a different logger.&lt;/p&gt;</description></item><item><title>Lesson 3: Loop Variable Fix — The Go 1.22 change that fixed a decade of bugs</title><link>/post/go/go-modern-loop-var/</link><pubDate>Sun, 13 Oct 2024 00:00:00 +0000</pubDate><guid>/post/go/go-modern-loop-var/</guid><description>&lt;p&gt;If you have written Go for more than a few weeks, you have hit this bug. Or you have reviewed code that had it and caught it. Or — if you were unlucky — you shipped it to production and spent an hour staring at a data race report wondering what on earth was happening. The loop variable capture bug was so common that it was essentially a Go rite of passage. Every Go tutorial mentioned it. Every linter had a rule for it. And for a decade, the answer was always &amp;ldquo;just copy the variable inside the loop.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Lesson 2: Enhanced HTTP Routing — Method patterns in net/http, no more gorilla/mux</title><link>/post/go/go-modern-http-routing/</link><pubDate>Sun, 11 Aug 2024 00:00:00 +0000</pubDate><guid>/post/go/go-modern-http-routing/</guid><description>&lt;p&gt;For most of my Go career, the standard library&amp;rsquo;s &lt;code&gt;net/http.ServeMux&lt;/code&gt; was something I used for toy services and immediately replaced with &lt;code&gt;gorilla/mux&lt;/code&gt; for anything real. The standard mux could not match HTTP methods. It could not extract path parameters. It matched prefixes in ways that surprised people. The moment a production service needed &lt;code&gt;GET /users/{id}&lt;/code&gt; and &lt;code&gt;POST /users&lt;/code&gt;, you reached for a dependency.&lt;/p&gt;
&lt;p&gt;Go 1.22 changed that. The enhanced &lt;code&gt;ServeMux&lt;/code&gt; now supports method matching, wildcard path parameters, and precedence rules that actually make sense. I rewrote three internal services to drop &lt;code&gt;gorilla/mux&lt;/code&gt; after reading the release notes, and every one of them got shorter and simpler. This lesson covers exactly what changed and when you still might want a third-party router.&lt;/p&gt;</description></item><item><title>Lesson 1: Range Over Integers and Iterators — for i := range 10 and the iterator protocol</title><link>/post/go/go-modern-range-iterators/</link><pubDate>Tue, 04 Jun 2024 00:00:00 +0000</pubDate><guid>/post/go/go-modern-range-iterators/</guid><description>&lt;p&gt;I have written &lt;code&gt;for i := 0; i &amp;lt; n; i++&lt;/code&gt; so many times that my fingers type it on autopilot. The three-clause for loop is fine — it works, everyone understands it, and Go has always had it. But when Go 1.22 shipped &lt;code&gt;for i := range 10&lt;/code&gt;, I stopped and stared at it for a moment. Not because it was complicated. Because it was so obviously the right thing that I wondered why it had taken this long.&lt;/p&gt;</description></item></channel></rss>