Enums in Go
This article explores emulating enums in Go, a language lacking native support. It covers defining custom types with strings or integers, utilizing the iota keyword, implementing interfaces, custom marshalling, and tools like go-enum.
Read original articleThis article discusses how to emulate enums in Go, a language that does not have native enum support. It explains the concept of enums and provides examples of how to define custom types using strings or integers. The use of the iota keyword to simplify enum declarations is also demonstrated. The article covers implementing the Stringer interface to get member names, custom marshalling and unmarshalling for enums, and reducing boilerplate code with tools like go-enum. It also addresses improving type safety by using structs and alternative approaches to define enums in Go. The author shares personal preferences and experiences regarding enum implementation in Go. Overall, the article serves as a comprehensive guide for working with enums in Go, offering various techniques and considerations for developers.
Related
Interface Upgrades in Go (2014)
The article delves into Go's interface upgrades, showcasing their role in encapsulation and decoupling. It emphasizes optimizing performance through wider interface casting, with examples from io and net/http libraries. It warns about complexities and advises cautious usage.
Common Interface Mistakes in Go
The article delves into interface mistakes in Go programming, stressing understanding of behavior-driven, concise interfaces. It warns against excessive, non-specific interfaces and offers guidance from industry experts for improvement.
Writing generic collection types in Go: the missing documentation
The blog post delves into challenges of implementing generic collection types in Go, focusing on creating a sortable Set. The author faces compilation errors, explores solutions, and discovers syntax for generic type constraints, enhancing understanding.
Know Go: Iterators in Go
Iterators in Go yield results one at a time, enhancing efficiency. They are detailed in function signatures, error handling, composition, and library impact. Compared to channels, iterators offer simplicity and efficiency.
Don't Use Booleans
Using enums over booleans in programming enhances code readability, prevents errors, and improves API extendability. Enumerations reduce mistakes, simplify code maintenance, and elevate software quality efficiently.
The Rust version is bith shorter and more readable - and probably more efficient - thanks to Rust enums and Rust error handling. I don't understand why golang doesn't copy Rust here. The error handling in particular could be a very simple change.
I am not a huge fan of go:generate and similar projects. They add a level of unknown that goes against the core Golang design values.
Still, the lack of enums and enum/sum types remains by far my biggest gripe about Go.
Go 2 needs to have more usable enums. And while I'm not a big fan of "adding more stuff" to languages, it wouldn't hurt Go to learn a couple of things from Rust.
The data structure for a token that makes most intuitive sense to me is a tagged union.
So I defined an „const iota“-style enum. Stuck it into a struct that has the appropriate fields to cover all the cases and it was fine.
Having some syntax sugar for tagged unions would be nice. Having exhaustiveness checks if you switch over them, could be useful in some cases.
But that’s not where my mental energy went at all.
Reading the bytes (runes) efficiently and correctly into the data structure however is the part that needs focus. Once the data is in shape, I‘m not „worried“ at all anymore. Sure a bit of extra support is nice, but also kind of superficial.
Also going further, dispatching on them is again never the tricky part. It’s handling the cases correctly and efficiently that has my focus.
In Clojure, a common thing is to write multimethods that dispatch on (namespaced) keywords. Similar in spirit and structure, but each method might now reside in a different namespace or not even be written by you. But I have never worried about exhaustive matching or similar. What’s in the method bodies is the important part.
https://pkg.go.dev/structs@master
What more sane languages would use attributes for, Go 1.23 will do it like this,
type myStruct struct {
_ struct.HostLayout
}
Lovely design. type Color int
const (
Red Color = iota
Green
Blue
)
var Colors = []string{ "Red", "Green", "Blue" }
Now (Colors[Red] == "Red") and (slices.Index(Colors, "Green") == Green).Related
Interface Upgrades in Go (2014)
The article delves into Go's interface upgrades, showcasing their role in encapsulation and decoupling. It emphasizes optimizing performance through wider interface casting, with examples from io and net/http libraries. It warns about complexities and advises cautious usage.
Common Interface Mistakes in Go
The article delves into interface mistakes in Go programming, stressing understanding of behavior-driven, concise interfaces. It warns against excessive, non-specific interfaces and offers guidance from industry experts for improvement.
Writing generic collection types in Go: the missing documentation
The blog post delves into challenges of implementing generic collection types in Go, focusing on creating a sortable Set. The author faces compilation errors, explores solutions, and discovers syntax for generic type constraints, enhancing understanding.
Know Go: Iterators in Go
Iterators in Go yield results one at a time, enhancing efficiency. They are detailed in function signatures, error handling, composition, and library impact. Compared to channels, iterators offer simplicity and efficiency.
Don't Use Booleans
Using enums over booleans in programming enhances code readability, prevents errors, and improves API extendability. Enumerations reduce mistakes, simplify code maintenance, and elevate software quality efficiently.