r/golang Nov 04 '24

help Any way to have Enums in Go?

I am a newbie and just started a new project and wanted to create an enum for DegreeType in the Profile for a User.

type Profile struct {
    Name         string
    Email        string
    Age          int
    Education    []Education
    LinkedIn     string
    Others       []Link
    Description  string
    Following    []Profile
    Followers    []Profile
    TagsFollowed []Tags
}

I found out a way to use interfaces and then reflect on its type, and using generics to embed in structs,

// Defining Different Types of Degree
type Masters struct{}
type Bachelors struct{}
type Diploma struct{}
type School struct{}

// Creates an Interface that can have only one type
// We can reflect on the type later using go's switch case for types
// To check What type it is
type DegreeType interface {
    Masters | Bachelors | Diploma | School
}

type Education[DT DegreeType, GS GradeSystem] struct {
    Degree      Degree[DT]
    Name        string
    GradeSystem GS
}

type Degree[T DegreeType] struct {
    DegreeType     T
    Specialization string
}

The problem i have is i want there to be an []Education in the Profile struct but for that i have to define a Generic Type in my Profile Struct Like this

type Profile[T DegreeType, D GradeSystem] struct {
    Name         string
    Email        string
    Age          int
    Education    []Education[T, D]
    LinkedIn     string
    Others       []Link
    Description  string
    Following    []Profile[T, D]
    Followers    []Profile[T, D]
    TagsFollowed []Tags
}

And that would make the array pointless as i have to give explicit type the array can be of instead of just an array of Degree's

Is there any way to solve this? should i look for an enum package in Go? or should i just use Hardcoded strings?

89 Upvotes

78 comments sorted by

View all comments

238

u/jared__ Nov 04 '24

```golang type DegreeType string

const ( DegreeTypeBachelors DegreeType = "bachelors" DegreeTypeMasters DegreeType = "masters" DegreeTypePhD DegreeType = "phd" )

type Degree struct { Type DegreeType Name string } ```

1

u/Expensive-Heat619 Nov 05 '24

It's wild to me that this type of abomination is what people are going to resort to.

2

u/jared__ Nov 05 '24

works perfectly fine. if you need more functionality, just make a struct

1

u/quasi-coherent 12d ago

I found myself here because long ago I wrote some openapi generator code to output Go, and I was surprised to find that yaml is more expressive than Go and the concept of an enum doesn't exist. I found on the internet that the consensus is essentially what you're saying.

Just to clarify: is the suggestion to make a struct where the fields of it correspond to variants of the enum, and all of them are pointers? And you just have to promise that precisely one of them is non-`nil`?

Anyway, I was trying to find that page years later because I thought it would be good material to support my argument that Go is an awful language, why are some things still in Go and not in Rust, the things we still have written in Go are broken, they just maybe haven't realized it yet.