Open
Description
There is alternative approach how to deal with enums in Go.
Example: https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example/blob/master/internal/trainer/domain/hour/availability.go
Article with motivation: https://threedots.tech/post/safer-enums-in-go/.
The idea is to use struct with private field and package level variables.
It would be great if exhaustive checks such enums as well, not only constants.
var (
Available = Availability{"available"}
NotAvailable = Availability{"not_available"}
TrainingScheduled = Availability{"training_scheduled"}
)
var availabilityValues = []Availability{
Available,
NotAvailable,
TrainingScheduled,
}
// Availability is enum.
//
// Using struct instead of `type Availability string` for enums allows us to ensure,
// that we have full control of what values are possible.
// With `type Availability string` you are able to create `Availability("i_can_put_anything_here")`
type Availability struct {
a string
}
func NewAvailabilityFromString(availabilityStr string) (Availability, error) {
for _, availability := range availabilityValues {
if availability.String() == availabilityStr {
return availability, nil
}
}
return Availability{}, errors.Errorf("unknown '%s' availability", availabilityStr)
}
// Every type in Go have zero value. In that case it's `Availability{}`.
// It's always a good idea to check if provided value is not zero!
func (h Availability) IsZero() bool {
return h == Availability{}
}
func (h Availability) String() string {
return h.a
}
Metadata
Assignees
Labels
No labels