Estoy tratando de representar un cromosoma simplificado, que consiste en N bases, cada una de las cuales solo puede ser una {A, C, T, G}
.
Me gustaría formalizar las restricciones con una enumeración, pero me pregunto cuál es la forma más idiomática de emular una enumeración en Go.
Respuestas:
Citando de las especificaciones de idioma: Iota
Entonces su código podría ser como
o
si quieres que las bases sean un tipo separado de int.
fuente
Ord(Base)
lo que no se limita a,0..3
sino que tiene los mismos límites que su tipo numérico subyacente. Es una elección de diseño de lenguaje, compromiso entre seguridad y rendimiento. Considere las comprobaciones "seguras" de tiempo de ejecución cada vez que toque unBase
valor escrito. ¿O cómo se debe definir el comportamiento deBase
valor de 'desbordamiento' para la aritmética y para++
y--
? Etc.iota + 1
para no comenzar en 0.Refiriéndose a la respuesta de jnml, puede evitar nuevas instancias de tipo Base al no exportar el tipo Base (es decir, escribirlo en minúsculas). Si es necesario, puede crear una interfaz exportable que tenga un método que devuelva un tipo base. Esta interfaz podría usarse en funciones externas que se ocupan de Bases, es decir
Dentro del paquete principal
a.Baser
es efectivamente como una enumeración ahora. Solo dentro del paquete puede definir nuevas instancias.fuente
base
se usa solo como receptor de métodos. Si sua
paquete exponga una función que toma un parámetro de tipobase
, entonces se volvería peligroso. De hecho, el usuario podría simplemente llamarlo con el valor literal 42, que la función aceptaríabase
ya que se puede convertir a un int. Para evitar esto, hacerbase
unstruct
:type base struct{value:int}
. Problema: ya no puede declarar bases como constantes, solo variables de módulo. Pero 42 nunca se lanzará a unbase
de ese tipo.Puedes hacerlo así:
Con este código el compilador debería verificar el tipo de enumeración
fuente
Es cierto que los ejemplos anteriores de uso
const
yiota
son las formas más idiomáticas de representar enumeraciones primitivas en Go. Pero, ¿qué sucede si está buscando una manera de crear una enumeración más completa, similar al tipo que vería en otro lenguaje como Java o Python?Una forma muy simple de crear un objeto que comienza a verse y sentirse como una enumeración de cadena en Python sería:
Supongamos que también desea algunos métodos de utilidad, como
Colors.List()
, yColors.Parse("red")
. Y sus colores eran más complejos y necesitaban ser una estructura. Entonces podrías hacer algo así:En ese momento, seguro que funciona, pero es posible que no le guste cómo debe definir los colores de forma repetitiva. Si en este punto desea eliminar eso, puede usar etiquetas en su estructura y reflexionar un poco para configurarlo, pero con suerte esto es suficiente para cubrir a la mayoría de las personas.
fuente
A partir de Go 1.4, la
go generate
herramienta se ha introducido junto con elstringer
comando que hace que su enumeración sea fácilmente depurable e imprimible.fuente
Estoy seguro de que tenemos muchas buenas respuestas aquí. Pero, solo pensé en agregar la forma en que he usado tipos enumerados
Esta es, con mucho, una de las formas idiomáticas en que podríamos crear tipos enumerados y usarlos en Go.
Editar:
Agregar otra forma de usar constantes para enumerar
fuente
Aquí hay un ejemplo que resultará útil cuando haya muchas enumeraciones. Utiliza estructuras en Golang, y se basa en Principios Orientados a Objetos para unirlos a todos en un pequeño paquete ordenado. Ninguno de los códigos subyacentes cambiará cuando se agregue o elimine una nueva enumeración. El proceso es:
enumeration items
: EnumItem . Tiene un tipo entero y de cadena.enumeration
como una lista deenumeration items
: Enumenum.Name(index int)
: devuelve el nombre para el índice dado.enum.Index(name string)
: devuelve el nombre para el índice dado.enum.Last()
: devuelve el índice y el nombre de la última enumeraciónAquí hay un código:
fuente