DEV Community

Cover image for Implementing Enum Types in Go
Leapcell
Leapcell

Posted on

Implementing Enum Types in Go

Cover

Preface

Enumeration types are a commonly used data type for representing a limited, predefined set of named constant values. In an enumeration type, each constant is an enum value, and all values are equal and unique.

Enumeration types are typically used to represent a set of related constants, such as days of the week, months, gender, etc. In other languages (such as Java and C), enumeration types are built-in. However, Go does not have a built-in enumeration type, so we need to use other approaches to implement similar enum functionality. This article will demonstrate how to implement an "enumeration type".

"Enumeration Types" in Go

The values of enumeration types are essentially constants, so we can use constants in Go to implement similar enum functionality. For example:

const ( Sunday = 1 Tuesday = 2 Wednesday = 3 Thursday = 4 Friday = 5 Saturday = 6 Monday = 7 ) 
Enter fullscreen mode Exit fullscreen mode

In this example, we use the const keyword to define a group of constants, where each constant's name represents an enum and its value corresponds to an integer.

Although this example achieves functionality similar to an enum type, it lacks some characteristics of true enum types, such as safety and constraints. To address these two issues, we can use custom types for improvement:

type WeekDay int const ( Sunday WeekDay = 1 Tuesday WeekDay = 2 Wednesday WeekDay = 3 Thursday WeekDay = 4 Friday WeekDay = 5 Saturday WeekDay = 6 Monday WeekDay = 7 ) 
Enter fullscreen mode Exit fullscreen mode

In the improved example, we define a custom type WeekDay to represent the days of the week. We then use the const keyword to define a group of constants, where each constant is assigned a specific value and constrained by the WeekDay type for type enforcement and checking. This allows us to use the enum value names to represent specific days of the week, and because of the custom type, the compiler can perform type checking, thereby improving type safety.

Gracefully Implementing Enums Using iota

From the previous example, it is easy to see that manually assigning values to each enum constant becomes quite cumbersome when multiple enum values are needed. To solve this problem, we can use the iota constant generator, which helps us generate sequential integer values.
For example, we can define a weekday enum type using iota:

type WeekDay int const ( Sunday WeekDay = iota Tuesday Wednesday Thursday Friday Saturday Monday ) 
Enter fullscreen mode Exit fullscreen mode

In this example, we use the auto-incrementing constant generator iota to define an enumeration type for weekdays. Each enum value is a constant of type WeekDay. Due to the auto-increment rule of iota, each enum value will automatically increment, generating a series of consecutive integer values.

Adding Methods to Custom Enums

type WeekDay int const ( Sunday WeekDay = iota Tuesday Wednesday Thursday Friday Saturday Monday ) 
Enter fullscreen mode Exit fullscreen mode

To make our implemented "enum type" more closely resemble enums in other languages such as Java, we can add methods to it.

Name()

Returns the name of the enum value.

// Name returns the name of the enum value func (w WeekDay) Name() string { if w < Sunday || w > Monday { return "Unknown" } return [...]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}[w] } 
Enter fullscreen mode Exit fullscreen mode

Original

Returns the position of the enum value in the enum type.

// Original: Since enum values in this type are essentially integer constants, // we can directly use the enum value as its index. func (w WeekDay) Original() int { return int(w) } 
Enter fullscreen mode Exit fullscreen mode

String()

Implements the String method for formatted output.

// Converts the enum value to a string for easy output func (w WeekDay) String() string { return w.Name() } 
Enter fullscreen mode Exit fullscreen mode

Values()

Returns a slice containing all enum values.

// Values returns a slice containing all enum values func Values() []WeekDay { return []WeekDay{Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} } 
Enter fullscreen mode Exit fullscreen mode

ValueOf()

Returns the corresponding enum value based on the name.

// ValueOf uses a switch statement to return the corresponding enum value based on the name func ValueOf(name string) (WeekDay, error) { switch name { case "Sunday": return Sunday, nil case "Monday": return Monday, nil case "Tuesday": return Tuesday, nil case "Wednesday": return Wednesday, nil case "Thursday": return Thursday, nil case "Friday": return Friday, nil case "Saturday": return Saturday, nil default: return 0, fmt.Errorf("invalid WeekDay name: %s", name) } } 
Enter fullscreen mode Exit fullscreen mode

Summary

In day-to-day development, enumeration types are very commonly used. Although Go does not have built-in enum types, it does not prevent us from implementing a similar "enum type" ourselves. When implementing it, we need to consider issues of type constraint and safety.

There are many ways to implement enum-like functionality. This article has introduced an approach using custom types. Once you understand the core idea, you can also implement similar enum functionality using structures or other techniques.


We are Leapcell, your top choice for hosting Go projects.

Leapcell

Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:

Multi-Language Support

  • Develop with Node.js, Python, Go, or Rust.

Deploy unlimited projects for free

  • pay only for usage — no requests, no charges.

Unbeatable Cost Efficiency

  • Pay-as-you-go with no idle charges.
  • Example: $25 supports 6.94M requests at a 60ms average response time.

Streamlined Developer Experience

  • Intuitive UI for effortless setup.
  • Fully automated CI/CD pipelines and GitOps integration.
  • Real-time metrics and logging for actionable insights.

Effortless Scalability and High Performance

  • Auto-scaling to handle high concurrency with ease.
  • Zero operational overhead — just focus on building.

Explore more in the Documentation!

Try Leapcell

Follow us on X: @LeapcellHQ


Read on our blog

Top comments (1)

Collapse
 
dotallio profile image
Dotallio

Great breakdown! Have you found a pattern for making reusable enum helpers, or do you write these methods fresh for every new type?