Question Details

No question body available.

Tags

go enums

Answers (1)

July 15, 2026 Score: 3 Rep: 21,360 Quality: Medium Completeness: 80%

Usage demonstrates:

  1. singleton identity (==)

  2. natural switch

  3. efficient lookup

  4. per-constant state

// Identity comparison
if notification.Type == notificationType.Progress {
    ...
}

// Switch switch notification.Type { case notificationType.Message: ... case notificationType.Progress: ... default: panic("unknown notification type") }

// Name and ordinal fmt.Println(notification.Type.Name()) // "Progress" fmt.Println(notification.Type.Ordinal()) // 1

// Lookup by name t := notificationType.Enum.ValueOf("Progress")

// Lookup by ordinal t := notificationType.Enum.ValueOfOrdinal(1)

// Enumerate all values for , t := range notificationType.Enum.Values() { fmt.Println(t.Name()) }

// Additional state fmt.Println(t.DisplayName())

NotificationType definition

package notificationType

var Message = newNotificationType("Message", "Message display name") var Progress = newNotificationType("Progress", "Progress display name")

var Enum = enum.NewEnum( Message, Progress, )

type NotificationType struct { enum.EnumValue[*NotificationType] displayName string }

func newNotificationType(name, displayName string) *NotificationType { return &NotificationType{ EnumValue: *enum.NewEnumValue[*NotificationType](name), displayName: displayName, } }

Enum.go

package enum

type value[T any] interface { Name() string setOrdinal(int) setDescriptor(*Enum[T]) }

type Enum[T any] struct { byName map[string]T byOrdinal []T }

func NewEnum[T value[T]](values ...T) *Enum[T] { d := &Enum[T]{ byName: make(map[string]T, len(values)), byOrdinal: make([]T, len(values)), } for i, value := range values { value.setOrdinal(i) value.setDescriptor(d) if
, exists := d.byName[value.Name()]; exists { panic("Duplicate enum constant: " + value.Name()) } d.byName[value.Name()] = value d.byOrdinal[i] = value } return d }

func (this Enum[T]) ValueOf(name string) T { v, ok := this.byName[name] assert.True(ok, "No enum constant %T.%s", this, name) return v }

func (this
Enum[T]) ValueOfOrdinal(ordinal int) T { assert.True(ordinal >= 0 && ordinal < len(this.byOrdinal), "Invalid ordinal %T: %d", this, ordinal) return this.byOrdinal[ordinal] }

func (this Enum[T]) Values() []T { return append([]T(nil), this.byOrdinal...) }

EnumValue.go

package enum

func ValueOf[T any](d
Enum[T], name string) T { return d.ValueOf(name) }

func ValueOfOrdinal[T any](d Enum[T], ordinal int) T { return d.ValueOfOrdinal(ordinal) }

func ValuesOf[T any](d
Enum[T]) []T { return d.Values() }

type EnumValue[T any] struct { enum Enum[T] name string ordinal int }

func NewEnumValue[T any](name string)
EnumValue[T] { return &EnumValue[T]{name: name, ordinal: -1} }

func (this EnumValue[T]) Name() string { return this.name }

func (this
EnumValue[T]) Ordinal() int { return this.ordinal }

func (this EnumValue[T]) Enum() Enum[T] { return this.enum }

func (this EnumValue[T]) String() string { return this.name }

func (this
EnumValue[T]) setOrdinal(ordinal int) { this.ordinal = ordinal }

func (this EnumValue[T]) setDescriptor(descriptor Enum[T]) { this.enum = descriptor }