<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Enum on WebDevStation</title>
    <link>https://webdevstation.com/tags/enum/</link>
    <description>1 article tagged Enum — tutorials, code examples and notes from building real systems, newest first.</description>
    <generator>Hugo</generator>
    <language>en</language>
    <managingEditor>Alex</managingEditor>
    <webMaster>Alex</webMaster>
    <copyright>© 2026 WebDevStation</copyright>
    <lastBuildDate>Fri, 23 May 2025 22:45:00 +0200</lastBuildDate>
    <atom:link href="https://webdevstation.com/tags/enum/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Implementing Enums in Golang: Patterns and Best Practices</title>
      <link>https://webdevstation.com/posts/implementing-enums-in-golang/</link>
      <pubDate>Fri, 23 May 2025 22:45:00 +0200</pubDate>
      <author>Alex</author>
      <guid isPermaLink="true">https://webdevstation.com/posts/implementing-enums-in-golang/</guid>
      <description>Discover effective techniques for implementing type-safe enums in Go using constants, iota, custom types, and string mapping. Learn best practices for enum-like…</description>
      <content:encoded><![CDATA[<p>Unlike many other programming languages, Golang doesn&rsquo;t have a built-in enum type. However, Go provides several elegant patterns to implement enum-like behavior with type safety and additional functionality. In this guide, we&rsquo;ll explore how to effectively implement and use enums in Golang.</p>
<h2 id="understanding-golang-enum-patterns">Understanding Golang Enum Patterns</h2>
<p>While Golang doesn&rsquo;t have a dedicated <code>enum</code> keyword like Java or TypeScript, it offers multiple approaches to create enumerated types. Let&rsquo;s explore these patterns from basic to advanced.</p>
<h2 id="basic-golang-enum-using-constants">Basic Golang Enum Using Constants</h2>
<p>The simplest way to implement an enum in Golang is using the <code>const</code> keyword with <code>iota</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// StatusPending is the initial status</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusPending</span> = <span style="color:#66d9ef">iota</span>  <span style="color:#75715e">// 0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// StatusActive indicates the item is active</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusActive</span>          <span style="color:#75715e">// 1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// StatusSuspended indicates the item is temporarily suspended</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusSuspended</span>       <span style="color:#75715e">// 2</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// StatusCancelled indicates the item is permanently cancelled</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusCancelled</span>       <span style="color:#75715e">// 3</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Status Pending:&#34;</span>, <span style="color:#a6e22e">StatusPending</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Status Active:&#34;</span>, <span style="color:#a6e22e">StatusActive</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Status Suspended:&#34;</span>, <span style="color:#a6e22e">StatusSuspended</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Status Cancelled:&#34;</span>, <span style="color:#a6e22e">StatusCancelled</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The <code>iota</code> identifier generates sequential integer constants. It starts at 0 and increments by 1 for each constant in the block. This approach is simple but lacks type safety.</p>
<h2 id="type-safe-golang-enum-pattern">Type-Safe Golang Enum Pattern</h2>
<p>To create a more type-safe enum, we can define a custom type:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Status</span> <span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusPending</span> <span style="color:#a6e22e">Status</span> = <span style="color:#66d9ef">iota</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusActive</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusSuspended</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">StatusCancelled</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">currentStatus</span> <span style="color:#a6e22e">Status</span> = <span style="color:#a6e22e">StatusActive</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// This would cause a compile error:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// currentStatus = 5</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Current status: %d\n&#34;</span>, <span style="color:#a6e22e">currentStatus</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>This pattern provides type safety, preventing you from assigning arbitrary integers to your enum type.</p>
<h2 id="string-representation-for-golang-enums">String Representation for Golang Enums</h2>
<p>One limitation of the basic enum patterns is that they don&rsquo;t provide a built-in way to convert enum values to strings. Let&rsquo;s implement this functionality:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Direction</span> <span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">North</span> <span style="color:#a6e22e">Direction</span> = <span style="color:#66d9ef">iota</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">East</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">South</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">West</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">d</span> <span style="color:#a6e22e">Direction</span>) <span style="color:#a6e22e">String</span>() <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [<span style="color:#f92672">...</span>]<span style="color:#66d9ef">string</span>{<span style="color:#e6db74">&#34;North&#34;</span>, <span style="color:#e6db74">&#34;East&#34;</span>, <span style="color:#e6db74">&#34;South&#34;</span>, <span style="color:#e6db74">&#34;West&#34;</span>}[<span style="color:#a6e22e">d</span>]
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">d</span> <span style="color:#a6e22e">Direction</span> = <span style="color:#a6e22e">East</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Direction:&#34;</span>, <span style="color:#a6e22e">d</span>)  <span style="color:#75715e">// Prints: Direction: East</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>By implementing the <code>String()</code> method, we enable automatic string conversion when printing the enum value.</p>
<h2 id="bitmask-enums-in-golang">Bitmask Enums in Golang</h2>
<p>For cases where you need to combine multiple enum values (flags), you can use bitmasks:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Permission</span> <span style="color:#66d9ef">uint</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Read</span> <span style="color:#a6e22e">Permission</span> = <span style="color:#ae81ff">1</span> <span style="color:#f92672">&lt;&lt;</span> <span style="color:#66d9ef">iota</span>  <span style="color:#75715e">// 1 (001)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Write</span>                        <span style="color:#75715e">// 2 (010)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Execute</span>                      <span style="color:#75715e">// 4 (100)</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">Permission</span>) <span style="color:#a6e22e">String</span>() <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">result</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">p</span><span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Read</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">result</span> <span style="color:#f92672">+=</span> <span style="color:#e6db74">&#34;Read &#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">p</span><span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Write</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">result</span> <span style="color:#f92672">+=</span> <span style="color:#e6db74">&#34;Write &#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">p</span><span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Execute</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">result</span> <span style="color:#f92672">+=</span> <span style="color:#e6db74">&#34;Execute &#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">result</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">perm</span> <span style="color:#a6e22e">Permission</span> = <span style="color:#a6e22e">Read</span> | <span style="color:#a6e22e">Write</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Permissions:&#34;</span>, <span style="color:#a6e22e">perm</span>)  <span style="color:#75715e">// Prints: Permissions: Read Write</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Check if Write permission is granted</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">perm</span><span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Write</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Write permission is granted&#34;</span>)
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Add Execute permission</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">perm</span> <span style="color:#f92672">|=</span> <span style="color:#a6e22e">Execute</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Updated permissions:&#34;</span>, <span style="color:#a6e22e">perm</span>)  <span style="color:#75715e">// Prints: Updated permissions: Read Write Execute</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>This pattern is particularly useful for configuration options or permission systems.</p>
<h2 id="advanced-golang-enum-with-behavior">Advanced Golang Enum with Behavior</h2>
<p>We can extend our enum pattern to include behavior by adding methods:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;strings&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">LogLevel</span> <span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Debug</span> <span style="color:#a6e22e">LogLevel</span> = <span style="color:#66d9ef">iota</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Info</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Warning</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Error</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Fatal</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// String returns the string representation of the log level</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">l</span> <span style="color:#a6e22e">LogLevel</span>) <span style="color:#a6e22e">String</span>() <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [<span style="color:#f92672">...</span>]<span style="color:#66d9ef">string</span>{<span style="color:#e6db74">&#34;DEBUG&#34;</span>, <span style="color:#e6db74">&#34;INFO&#34;</span>, <span style="color:#e6db74">&#34;WARNING&#34;</span>, <span style="color:#e6db74">&#34;ERROR&#34;</span>, <span style="color:#e6db74">&#34;FATAL&#34;</span>}[<span style="color:#a6e22e">l</span>]
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Color returns ANSI color code for console output</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">l</span> <span style="color:#a6e22e">LogLevel</span>) <span style="color:#a6e22e">Color</span>() <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [<span style="color:#f92672">...</span>]<span style="color:#66d9ef">string</span>{
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;\033[36m&#34;</span>, <span style="color:#75715e">// Cyan for Debug</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;\033[32m&#34;</span>, <span style="color:#75715e">// Green for Info</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;\033[33m&#34;</span>, <span style="color:#75715e">// Yellow for Warning</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;\033[31m&#34;</span>, <span style="color:#75715e">// Red for Error</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;\033[35m&#34;</span>, <span style="color:#75715e">// Magenta for Fatal</span>
</span></span><span style="display:flex;"><span>    }[<span style="color:#a6e22e">l</span>]
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Log prints a message with the appropriate level and color</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">l</span> <span style="color:#a6e22e">LogLevel</span>) <span style="color:#a6e22e">Log</span>(<span style="color:#a6e22e">message</span> <span style="color:#66d9ef">string</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">reset</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">&#34;\033[0m&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;%s[%s]%s %s\n&#34;</span>, <span style="color:#a6e22e">l</span>.<span style="color:#a6e22e">Color</span>(), <span style="color:#a6e22e">l</span>.<span style="color:#a6e22e">String</span>(), <span style="color:#a6e22e">reset</span>, <span style="color:#a6e22e">message</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Info</span>.<span style="color:#a6e22e">Log</span>(<span style="color:#e6db74">&#34;Application started&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Debug</span>.<span style="color:#a6e22e">Log</span>(<span style="color:#e6db74">&#34;Connection details: localhost:8080&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Warning</span>.<span style="color:#a6e22e">Log</span>(<span style="color:#e6db74">&#34;High memory usage detected&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Error</span>.<span style="color:#a6e22e">Log</span>(<span style="color:#e6db74">&#34;Failed to connect to database&#34;</span>)
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Parse log level from string</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">userInput</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">&#34;warning&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">level</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">Debug</span>; <span style="color:#a6e22e">level</span> <span style="color:#f92672">&lt;=</span> <span style="color:#a6e22e">Fatal</span>; <span style="color:#a6e22e">level</span><span style="color:#f92672">++</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">EqualFold</span>(<span style="color:#a6e22e">userInput</span>, <span style="color:#a6e22e">level</span>.<span style="color:#a6e22e">String</span>()) {
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Parsed log level: %s\n&#34;</span>, <span style="color:#a6e22e">level</span>)
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">break</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>This example demonstrates how to add rich behavior to enum types, making them more powerful and expressive.</p>
<h2 id="enum-validation-in-golang">Enum Validation in Golang</h2>
<p>When accepting enum values from external sources (like API requests), validation is crucial:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;encoding/json&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">PaymentMethod</span> <span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">CreditCard</span> <span style="color:#a6e22e">PaymentMethod</span> = <span style="color:#66d9ef">iota</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">DebitCard</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">BankTransfer</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">PayPal</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Crypto</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">PaymentMethod</span>) <span style="color:#a6e22e">String</span>() <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [<span style="color:#f92672">...</span>]<span style="color:#66d9ef">string</span>{<span style="color:#e6db74">&#34;&#34;</span>, <span style="color:#e6db74">&#34;CreditCard&#34;</span>, <span style="color:#e6db74">&#34;DebitCard&#34;</span>, <span style="color:#e6db74">&#34;BankTransfer&#34;</span>, <span style="color:#e6db74">&#34;PayPal&#34;</span>, <span style="color:#e6db74">&#34;Crypto&#34;</span>}[<span style="color:#a6e22e">p</span>]
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">PaymentMethod</span>) <span style="color:#a6e22e">IsValid</span>() <span style="color:#66d9ef">bool</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">p</span> <span style="color:#f92672">&gt;=</span> <span style="color:#a6e22e">CreditCard</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">p</span> <span style="color:#f92672">&lt;=</span> <span style="color:#a6e22e">Crypto</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// MarshalJSON custom JSON marshaling</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">PaymentMethod</span>) <span style="color:#a6e22e">MarshalJSON</span>() ([]<span style="color:#66d9ef">byte</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Marshal</span>(<span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">String</span>())
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// UnmarshalJSON custom JSON unmarshaling</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">PaymentMethod</span>) <span style="color:#a6e22e">UnmarshalJSON</span>(<span style="color:#a6e22e">data</span> []<span style="color:#66d9ef">byte</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">s</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Unmarshal</span>(<span style="color:#a6e22e">data</span>, <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">s</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Map string to enum value</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">methodMap</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">map</span>[<span style="color:#66d9ef">string</span>]<span style="color:#a6e22e">PaymentMethod</span>{
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;CreditCard&#34;</span>:    <span style="color:#a6e22e">CreditCard</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;DebitCard&#34;</span>:     <span style="color:#a6e22e">DebitCard</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;BankTransfer&#34;</span>:  <span style="color:#a6e22e">BankTransfer</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;PayPal&#34;</span>:        <span style="color:#a6e22e">PayPal</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;Crypto&#34;</span>:        <span style="color:#a6e22e">Crypto</span>,
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">val</span>, <span style="color:#a6e22e">ok</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">methodMap</span>[<span style="color:#a6e22e">s</span>]; <span style="color:#a6e22e">ok</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">*</span><span style="color:#a6e22e">p</span> = <span style="color:#a6e22e">val</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;invalid payment method: %s&#34;</span>, <span style="color:#a6e22e">s</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Payment</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Amount</span>  <span style="color:#66d9ef">float64</span>       <span style="color:#e6db74">`json:&#34;amount&#34;`</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Method</span>  <span style="color:#a6e22e">PaymentMethod</span> <span style="color:#e6db74">`json:&#34;method&#34;`</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Details</span> <span style="color:#66d9ef">string</span>        <span style="color:#e6db74">`json:&#34;details&#34;`</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">ProcessPayment</span>(<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">Payment</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> !<span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Method</span>.<span style="color:#a6e22e">IsValid</span>() {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;invalid payment method: %v&#34;</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Method</span>)
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Processing %s payment of $%.2f\n&#34;</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Method</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Amount</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Valid payment</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">paymentJSON</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">`{&#34;amount&#34;: 99.99, &#34;method&#34;: &#34;PayPal&#34;, &#34;details&#34;: &#34;user@example.com&#34;}`</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">payment</span> <span style="color:#a6e22e">Payment</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Unmarshal</span>([]byte(<span style="color:#a6e22e">paymentJSON</span>), <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">payment</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Error:&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">ProcessPayment</span>(<span style="color:#a6e22e">payment</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Error:&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Invalid payment</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">invalidJSON</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">`{&#34;amount&#34;: 199.99, &#34;method&#34;: &#34;Bitcoin&#34;, &#34;details&#34;: &#34;wallet_address&#34;}`</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">invalidPayment</span> <span style="color:#a6e22e">Payment</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Unmarshal</span>([]byte(<span style="color:#a6e22e">invalidJSON</span>), <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">invalidPayment</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Error:&#34;</span>, <span style="color:#a6e22e">err</span>)  <span style="color:#75715e">// This will print: Error: invalid payment method: Bitcoin</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>This pattern demonstrates how to handle JSON serialization/deserialization and validation for enum types, which is essential for API development.</p>
<h2 id="implementing-stringer-interface-automatically">Implementing Stringer Interface Automatically</h2>
<p>Writing the <code>String()</code> method manually for large enums can be tedious. The <code>stringer</code> tool can generate this code for you:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">//go:generate stringer -type=Season</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Season</span> <span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Winter</span> <span style="color:#a6e22e">Season</span> = <span style="color:#66d9ef">iota</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Spring</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Summer</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Autumn</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">Winter</span>)  <span style="color:#75715e">// Prints: Winter</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">Summer</span>)  <span style="color:#75715e">// Prints: Summer</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>To use this, install the stringer tool and run go generate:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go install golang.org/x/tools/cmd/stringer@latest
</span></span><span style="display:flex;"><span>go generate
</span></span></code></pre></div><p>This will create a file named <code>season_string.go</code> with the <code>String()</code> method implementation.</p>
<h2 id="conclusion">Conclusion</h2>
<p>While Golang doesn&rsquo;t have built-in enum types, it provides flexible and powerful patterns to implement them. From simple constants to type-safe enums with behavior, these patterns offer different trade-offs in terms of simplicity, type safety, and functionality.</p>
<p>By choosing the right enum pattern for your specific use case, you can write more maintainable, type-safe, and expressive Go code. Remember that the best pattern depends on your requirements - use simpler approaches for basic needs and more advanced patterns when additional functionality is required.</p>
<p>The absence of a dedicated enum type in Golang is not a limitation but rather an opportunity to implement exactly what you need with the language&rsquo;s existing features.</p>
<p>For more on the language features behind these patterns, see <a href="/posts/example-of-how-generics-simplify-golang/">how Golang generics minimize the amount of code you need to write</a> and <a href="/posts/mastering-for-loops-in-go/">mastering Golang for loops</a>. For what has landed in the language more recently, see <a href="/posts/exciting-features-in-go-1-25/">exciting features coming in Go 1.25</a>.</p>]]></content:encoded>
      <category>Go Programming</category>
    </item>
  </channel>
</rss>
