枚舉(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中文網其他相關文章!