枚举(enumeration)的缩写,是一种特殊的数据类型,表示一组命名值。它用于定义概念上相关的常量值的集合,提高代码可读性并减少由于使用任意文字值而导致的错误。
// 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 本身不支持枚举。然而,在 Go 中定义枚举的流行方法是使用 iota 方法。
package main type TrafficLight int const ( RED TrafficLight = iota // 0 GREEN // 1 BLUE // 2 ) func main() { fmt.Println(RED) // Output: 0 }
但是,以这种方式处理枚举时存在一些问题:
xybor-x/enum 库为 Go 枚举提供了优雅、易于使用且功能强大的解决方案,无需生成代码。
有一些类型的枚举可以与 xybor-x/enum 一起使用,请选择最合适的一种。
优点?
缺点?
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" }
优点?
缺点?
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 是最适合一般情况的枚举。然而,它只提供基本的类型安全。如果您想要更严格的,请考虑使用 SafeEnum。
// WrapEnum cannot prevent this type of invalid declaration. // Consider using SafeEnum. r := Role(42)
SafeEnum 定义了一个强类型安全枚举。与 WrapEnum 一样,它提供了一组内置方法来简化枚举的使用。
SafeEnum 强制执行严格的类型安全,确保只允许预定义的枚举值。它可以防止意外创建新的枚举类型,从而提供一组有保证的有效值。
优点?
缺点?
为什么持续支持很重要?
一些静态分析工具(例如 bazel 的 nogo、具有详尽扩展的 golangci-lint)支持检查常量枚举中的详尽 switch 语句。通过选择具有持续支持的枚举,您可以在这些工具中启用此功能。
// Enum in Java enum TrafficLight { RED, YELLOW, GREEN }
xybor-x/enum:https://github.com/xybor-x/enum
中:https://medium.com/@huykingsofm/enum-handling-in-go-a2727154435e
越南语 viblo:https://viblo.asia/p/cac-van-de-cua-go-enum-va-cach-giai-quyet-voi-xybor-xenum-Yym401A9J91
以上是Go Enum 与 xybor-x/enum 的问题及解决方案的详细内容。更多信息请关注PHP中文网其他相关文章!