Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go: How to use enum as a type?

Tags:

enums

go

I have a list of events (enum) which defines the particular event:

package events

const (
    NEW_USER       = "NEW_USER"
    DIRECT_MESSAGE = "DIRECT_MESSAGE"
    DISCONNECT     = "DISCONNECT"
)

And there is a struct that will use this enum as one of its attribute

type ConnectionPayload struct {
    EventName    string      `json:"eventName"`
    EventPayload interface{} `json:"eventPayload"`
}

Is there a way I can use enum as a type for EventName instead of string?

This is possible in typescript not sure how to do it in golang.

I want the developers to forcefully use correct event name using the enum instead of making a mistake by using any random string for eventname.

like image 476
Karan Kumar Avatar asked Dec 05 '25 19:12

Karan Kumar


1 Answers

There is no enum type at the moment in go, and there currently isn't a direct way to enforce the same rules as what typescript does.


A common practice in go is to use the suggestion posted by @ttrasn :

define a custom type, and typed constants with your "enum" values :

type EventName string

const (
    NEW_USER       EventName = "NEW_USER"
    DIRECT_MESSAGE EventName = "DIRECT_MESSAGE"
    DISCONNECT     EventName = "DISCONNECT"
)

This allows you to flag, in your go code, the places where you expect such a value :

// example function signature :
func OnEvent(e EventName, id int) error { ... }

// example struct :
type ConnectionPayload struct {
    EventName    EventName  `json:"eventName"`
    EventPayload interface{} `json:"eventPayload"`
}

and it will prevent assigning a plain string to an EventName

var str string = "foo"
var ev EventName

ev = str // won't compile
OnEvent(str, 42) // won't compile

The known limitations are :

  • in go, there is always a zero value :
    var ev EventName  // ev is ""
    
  • string litterals are not the same as typed variables, and can be assigned :
    var ev EventName = "SOMETHING_ELSE"
    
  • casting is allowed :
    var str string = "foo"
    var ev EventName = EventName(str)
    
  • there is no check on unmarshalling :
    jsn := []byte(`{"eventName":"SOMETHING_ELSE","eventPayload":"some message"}`)
    err := json.Unmarshal(jsn, &payload) // no error
    

https://go.dev/play/p/vMUTpvH8DBb

If you want some stricter checking, you would have to write a validator or a custom unmarshaler yourself.

like image 134
LeGEC Avatar answered Dec 08 '25 16:12

LeGEC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!