Estou tentando representar um cromossomo simplificado, que consiste em N bases, cada uma das quais pode ser apenas uma {A, C, T, G}
.
Gostaria de formalizar as restrições com um enum, mas estou me perguntando qual é a maneira mais idiomática de emular um enum no Go.
Respostas:
Citando as especificações de idioma: Iota
Portanto, seu código pode ser como
ou
se você deseja que as bases sejam um tipo separado do int.
fonte
Ord(Base)
não está limitado a,0..3
mas tem os mesmos limites que seu tipo numérico subjacente. É uma escolha de design de linguagem, compromisso entre segurança e desempenho. Considere verificações de limite de tempo de execução "seguras" sempre que tocar em umBase
valor digitado. Ou como se deve definir o comportamento deBase
valor "transbordante" para aritmética e para++
e--
? Eiota + 1
para não começar a 0.Referindo-se à resposta do jnml, você pode impedir novas instâncias do tipo Base não exportando o tipo Base (ex .: escreva-o em minúsculas). Se necessário, você pode criar uma interface exportável que possua um método que retorne um tipo de base. Essa interface pode ser usada em funções externas que lidam com bases, ou seja,
Dentro do pacote principal
a.Baser
está efetivamente como um enum agora. Somente dentro de um pacote você pode definir novas instâncias.fonte
base
é usado apenas como receptor de método. Se o seua
pacote expor uma função usando um parâmetro do tipobase
, isso se tornaria perigoso. De fato, o usuário poderia chamá-lo apenas com o valor literal 42, que a função aceitaria,base
pois pode ser convertida para um int. Para evitar isso, façabase
umstruct
:type base struct{value:int}
. Problema: você não pode mais declarar bases como constantes, apenas variáveis de módulo. Mas 42 nunca serão convertidos para umbase
desse tipo.Você pode fazer isso assim:
Com este código, o compilador deve verificar o tipo de enum
fonte
É verdade que os exemplos acima de usar
const
eiota
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:
Suponha que você também queira alguns métodos utilitários, como
Colors.List()
, eColors.Parse("red")
. E suas cores eram mais complexas e precisavam ser uma estrutura. Então você pode fazer algo parecido com isto: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.
fonte
A partir do Go 1.4, a
go generate
ferramenta foi introduzida juntamente com ostringer
comando que torna seu enum facilmente depurável e imprimível.fonte
Estou certo de que temos muitas boas respostas aqui. Mas, apenas pensei em adicionar a maneira como usei tipos enumerados
Essa é de longe uma das maneiras idiomáticas em que poderíamos criar tipos enumerados e usar no Go.
Editar:
Adicionando outra maneira de usar constantes para enumerar
fonte
Aqui está um exemplo que será útil quando houver muitas enumerações. Ele usa estruturas em Golang e se baseia em Princípios Orientados a Objetos para amarrá-los todos juntos em um pequeno embrulho. Nenhum do código subjacente será alterado quando uma nova enumeração for adicionada ou excluída. O processo é:
enumeration items
: EnumItem . Tem um número inteiro e um tipo de sequência.enumeration
como uma lista deenumeration items
: Enumenum.Name(index int)
: retorna o nome para o índice especificado.enum.Index(name string)
: retorna o nome para o índice especificado.enum.Last()
: retorna o índice e o nome da última enumeraçãoAqui está um código:
fonte