An enum, short for enumeration, is a special data type that represents a set of named values. It is used to define a collection of constant values that are conceptually related, improving code readability and reducing errors caused by the use of arbitrary literal values.
// Enum in Java enum TrafficLight { RED, YELLOW, GREEN }
# Enum in Python from enum import Enum class TrafficLight(Enum): RED = 1 GREEN = 2 BLUE = 3
Go doesn’t support enum natively. However, there is a popular way to define an enum in Go is using iota approach.
package main type TrafficLight int const ( RED TrafficLight = iota // 0 GREEN // 1 BLUE // 2 ) func main() { fmt.Println(RED) // Output: 0 }
However, there are some problems when dealing with enum in this way:
The xybor-x/enum libray provides elegant, easy-to-use, and powerful solutions for Go enum with no code generation.
There are some types of enum which you can work with xybor-x/enum, please choose the most suitable one.
Pros ?
Cons ?
package main type Role int const ( RoleUser Role = iota RoleAdmin ) func init() { enum.Map(RoleUser, "user") enum.Map(RoleAdmin, "admin") // Optional: ensure no new enum values can be added to Role. enum.Finalize[Role]() } func main() { // Print the corresponding string. fmt.Println(enum.ToString(RoleUser)) // Output: user // Print out all valid enums. fmt.Println(enum.All[Role]()) // Output: [0 1] // Parse an enum from int. r1, ok := enum.FromInt[Role](1) fmt.Println(ok) // Output: true fmt.Println(enum.ToString(r1)) // Output: admin // Parse an enum from string. r2, ok := enum.FromString[Role]("admin") fmt.Println(ok) // Output: true fmt.Println(r2) // Output: 1 // Serialize json. data, err := enum.MarshalJSON(RoleUser) fmt.Println(err) // Output: nil fmt.Println(string(data)) // Output: "user" }
Pros ?
Cons ?
package main // Only need to change the two following lines fromthe Basic enum. type role any type Role = enum.WrapEnum[role] const ( RoleUser Role = iota RoleAdmin ) func init() { enum.Map(RoleUser, "user") enum.Map(RoleAdmin, "admin") // Optional: ensure no new enum values can be added to Role. enum.Finalize[Role]() } func main() { // Print the corresponding string. No need to use enum.ToString. fmt.Println(RoleUser) // Output: user // Print out all valid enums. fmt.Println(enum.All[Role]()) // Output: [user admin] // Parse an enum from int. r1, ok := enum.FromInt[Role](1) fmt.Println(ok) // Output: true fmt.Println(r1) // Output: admin // Parse an enum from string. r2, ok := enum.FromString[Role]("admin") fmt.Println(ok) // Output: true fmt.Println(r2) // Output: admin // Now you can use json.Marshal instead of enum.MarshalJSON. data, err := json.Marshal(RoleUser) fmt.Println(err) // Output: nil fmt.Println(string(data)) // Output: "user" }
WrapEnum is the most suitable enum for general cases. However, it only provides basic type safety. If you want a stricter one, consider using SafeEnum.
// WrapEnum cannot prevent this type of invalid declaration. // Consider using SafeEnum. r := Role(42)
SafeEnum defines a strong type-safe enum. Like WrapEnum, it provides a set of built-in methods to simplify working with enums.
The SafeEnum enforces strict type safety, ensuring that only predefined enum values are allowed. It prevents the accidental creation of new enum types, providing a guaranteed set of valid values.
Pros ?
Cons ?
Why is constant-support important?
Some static analysis tools (such as nogo for bazel, golangci-lint with exhaustive extension) support checking for exhaustive switch statements in constant enums. By choosing an enum with constant support, you can enable this functionality in these tools.
// Enum in Java enum TrafficLight { RED, YELLOW, GREEN }
xybor-x/enum: https://github.com/xybor-x/enum
Medium: https://medium.com/@huykingsofm/enum-handling-in-go-a2727154435e
Vietnamese viblo: https://viblo.asia/p/cac-van-de-cua-go-enum-va-cach-giai-quyet-voi-xybor-xenum-Yym401A9J91
The above is the detailed content of Go Enum's problems and solutions with xybor-x/enum. For more information, please follow other related articles on the PHP Chinese website!