I'd like to propose that enum be added to Go as a special kind of type. The examples below are borrowed from the protobuf example.
Enums in Go today
type SearchRequest int
var (
SearchRequestUNIVERSAL SearchRequest = 0 // UNIVERSAL
SearchRequestWEB SearchRequest = 1 // WEB
SearchRequestIMAGES SearchRequest = 2 // IMAGES
SearchRequestLOCAL SearchRequest = 3 // LOCAL
SearchRequestNEWS SearchRequest = 4 // NEWS
SearchRequestPRODUCTS SearchRequest = 5 // PRODUCTS
SearchRequestVIDEO SearchRequest = 6 // VIDEO
)
type SearchRequest string
var (
SearchRequestUNIVERSAL SearchRequest = "UNIVERSAL"
SearchRequestWEB SearchRequest = "WEB"
SearchRequestIMAGES SearchRequest = "IMAGES"
SearchRequestLOCAL SearchRequest = "LOCAL"
SearchRequestNEWS SearchRequest = "NEWS"
SearchRequestPRODUCTS SearchRequest = "PRODUCTS"
SearchRequestVIDEO SearchRequest = "VIDEO"
)
// IsValid has to be called everywhere input happens, or you risk bad data - no guarantees
func (sr SearchRequest) IsValid() bool {
switch sr {
case SearchRequestUNIVERSAL, SearchRequestWEB...:
return true
}
return false
}
How it might look with language support
enum SearchRequest int {
0 // UNIVERSAL
1 // WEB
2 // IMAGES
3 // LOCAL
4 // NEWS
5 // PRODUCTS
6 // VIDEO
}
enum SearchRequest string {
"UNIVERSAL"
"WEB"
"IMAGES"
"LOCAL"
"NEWS"
"PRODUCTS"
"VIDEO"
}
The pattern is common enough that I think it warrants special casing, and I believe that it makes code more readable. At the implementation layer, I would imagine that the majority of cases can be checked at compile time, some of which already happen today, while others are near impossible or require significant tradeoffs.
- Safety for exported types: nothing prevents someone from doing
SearchRequest(99) or SearchRequest("MOBILEAPP"). Current workarounds include making an unexported type with options, but that often makes the resulting code harder to use / document.
- Runtime safety: Just like protobuf is going to check for validity while unmarshaling, this provides language wide validation, anytime that an enum is instantiated.
- Tooling / Documentation: many packages today put valid options into field comments, but not everyone does it and there is no guarantee that the comments aren't outdated.
Things to Consider
- Nil: by implementing
enum on top of the type system, I don't believe this should require special casing. If someone wants nil to be valid, then the enum should be defined as a pointer.
- Default value / runtime assignments: This is one of the tougher decisions to make. What if the Go default value isn't defined as a valid enum? Static analysis can mitigate some of this at compile time, but there would need to be a way to handle outside input.
I don't have any strong opinions on the syntax. I do believe this could be done well and would make a positive impact on the ecosystem.
I'd like to propose that enum be added to Go as a special kind of
type. The examples below are borrowed from the protobuf example.Enums in Go today
How it might look with language support
The pattern is common enough that I think it warrants special casing, and I believe that it makes code more readable. At the implementation layer, I would imagine that the majority of cases can be checked at compile time, some of which already happen today, while others are near impossible or require significant tradeoffs.
SearchRequest(99)orSearchRequest("MOBILEAPP"). Current workarounds include making an unexported type with options, but that often makes the resulting code harder to use / document.Things to Consider
enumon top of the type system, I don't believe this should require special casing. If someone wantsnilto be valid, then the enum should be defined as a pointer.I don't have any strong opinions on the syntax. I do believe this could be done well and would make a positive impact on the ecosystem.