Rumah >pembangunan bahagian belakang >Golang >Pergi masalah dan penyelesaian Enum dengan xybor-x/enum

Pergi masalah dan penyelesaian Enum dengan xybor-x/enum

DDD
DDDasal
2024-12-19 18:44:11877semak imbas

Apakah enum?

Enum, singkatan daripada penghitungan, ialah jenis data khas yang mewakili satu set nilai yang dinamakan. Ia digunakan untuk mentakrifkan koleksi nilai malar yang berkaitan secara konsep, meningkatkan kebolehbacaan kod dan mengurangkan ralat yang disebabkan oleh penggunaan nilai literal sewenang-wenangnya.

// Enum in Java
enum TrafficLight {
    RED, YELLOW, GREEN
}
# Enum in Python
from enum import Enum

class TrafficLight(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

Enum dalam Go

Go tidak menyokong enum secara asli. Walau bagaimanapun, terdapat cara popular untuk mentakrifkan enum dalam Go ialah menggunakan pendekatan iota.

package main

type TrafficLight int

const (
    RED TrafficLight = iota // 0
    GREEN                   // 1
    BLUE                    // 2
)

func main() {
    fmt.Println(RED) // Output: 0
}

Walau bagaimanapun, terdapat beberapa masalah apabila berurusan dengan enum dengan cara ini:

  • Kekurangan Kaedah Terbina dalam: Tiada sokongan langsung untuk ciri seperti menyenaraikan semua nilai enum atau menukar antara rentetan dan enum.
  • Keselamatan Jenis Terhad: Enum biasanya diwakili menggunakan jenis asas (cth., int atau rentetan), yang meningkatkan risiko tugasan yang tidak diingini.
  • Kerumitan Pensirilan dan Penyahserikatan: Pemetaan enum ke dan dari format seperti JSON memerlukan pengendalian tambahan.

Perpustakaan xybor-x/enum

Go Enum’s problems and solutions with xybor-x/enum

Libray xybor-x/enum menyediakan penyelesaian yang elegan, mudah digunakan dan berkuasa untuk Go enum tanpa penjanaan kod.

Terdapat beberapa jenis enum yang boleh anda gunakan dengan xybor-x/enum, sila pilih yang paling sesuai.

enum asas

Kebaikan ?

  • Mudah.
  • Menyokong nilai malar.

Keburukan ?

  • Tiada kaedah terbina dalam.
  • Tiada jenis keselamatan.
  • Kurang sokongan bersiri dan penyahserikatan. Seperti enum tradisional, enum asas tidak mempunyai kaedah terbina dalam. Tetapi anda boleh menggunakan fungsi utiliti xybor-x/enum untuk mengendalikan jenis enum ini.
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"
}

WrapEnum

Kebaikan ?

  • Menyokong nilai malar.
  • Menyediakan banyak kaedah terbina dalam yang berguna.
  • Sokongan pensirilan dan penyahserilan penuh di luar kotak.

Keburukan ?

  • Hanya menyediakan keselamatan jenis asas.
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 ialah enum yang paling sesuai untuk kes umum. Walau bagaimanapun, ia hanya menyediakan keselamatan jenis asas. Jika anda mahukan yang lebih ketat, pertimbangkan untuk menggunakan SafeEnum.

// WrapEnum cannot prevent this type of invalid declaration.
// Consider using SafeEnum.
r := Role(42)

SafeEnum

SafeEnum mentakrifkan enum jenis selamat yang kuat. Seperti WrapEnum, ia menyediakan satu set kaedah terbina dalam untuk memudahkan kerja dengan enum.

SafeEnum menguatkuasakan keselamatan jenis yang ketat, memastikan bahawa hanya nilai enum pratakrif dibenarkan. Ia menghalang penciptaan jenis enum baharu secara tidak sengaja, memberikan set nilai yang sah yang terjamin.

Kebaikan ?

  • Memberikan keselamatan jenis yang kuat.
  • Menyediakan banyak kaedah terbina dalam yang berguna.
  • Sokongan pensirilan dan penyahserilan penuh di luar kotak.

Keburukan ?

  • Tidak menyokong nilai malar.

Mengapakah sokongan berterusan penting?

Sesetengah alat analisis statik (seperti nogo untuk bazel, golangci-lint dengan sambungan menyeluruh) menyokong penyemakan penyataan suis lengkap dalam enum tetap. Dengan memilih enum dengan sokongan berterusan, anda boleh mendayakan fungsi ini dalam alatan ini.

// Enum in Java
enum TrafficLight {
    RED, YELLOW, GREEN
}

Rujukan

xybor-x/enum: https://github.com/xybor-x/enum

Medium: https://medium.com/@huykingsofm/enum-handling-in-go-a2727154435e
Viblo Vietnam: https://viblo.asia/p/cac-van-de-cua-go-enum-va-cach-giai-quyet-voi-xybor-xenum-Yym401A9J91

Atas ialah kandungan terperinci Pergi masalah dan penyelesaian Enum dengan xybor-x/enum. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn