É verdade que os exemplos acima de usar const
e iota
são as formas mais idiomáticas de representar enums primitivas no Go. Mas e se você estiver procurando uma maneira de criar uma enumeração mais completa, semelhante ao tipo que você veria em outra linguagem como Java ou Python?
Uma maneira muito simples de criar um objeto que começa a se parecer com um enum de string no Python seria:
package main
import (
"fmt"
)
var Colors = newColorRegistry()
func newColorRegistry() *colorRegistry {
return &colorRegistry{
Red: "red",
Green: "green",
Blue: "blue",
}
}
type colorRegistry struct {
Red string
Green string
Blue string
}
func main() {
fmt.Println(Colors.Red)
}
Suponha que você também queira alguns métodos utilitários, como Colors.List()
, e Colors.Parse("red")
. E suas cores eram mais complexas e precisavam ser uma estrutura. Então você pode fazer algo parecido com isto:
package main
import (
"errors"
"fmt"
)
var Colors = newColorRegistry()
type Color struct {
StringRepresentation string
Hex string
}
func (c *Color) String() string {
return c.StringRepresentation
}
func newColorRegistry() *colorRegistry {
red := &Color{"red", "F00"}
green := &Color{"green", "0F0"}
blue := &Color{"blue", "00F"}
return &colorRegistry{
Red: red,
Green: green,
Blue: blue,
colors: []*Color{red, green, blue},
}
}
type colorRegistry struct {
Red *Color
Green *Color
Blue *Color
colors []*Color
}
func (c *colorRegistry) List() []*Color {
return c.colors
}
func (c *colorRegistry) Parse(s string) (*Color, error) {
for _, color := range c.List() {
if color.String() == s {
return color, nil
}
}
return nil, errors.New("couldn't find it")
}
func main() {
fmt.Printf("%s\n", Colors.List())
}
Nesse ponto, com certeza funciona, mas você pode não gostar de como definir cores repetidamente. Se, nesse ponto, você quiser eliminar isso, use tags na sua estrutura e faça algumas reflexões sofisticadas para configurá-la, mas espero que isso seja suficiente para cobrir a maioria das pessoas.