J'essaie de représenter un chromosome simplifié, qui se compose de N bases, dont chacune ne peut être qu'une {A, C, T, G}
.
J'aimerais formaliser les contraintes avec une énumération, mais je me demande quelle est la manière la plus idiomatique d'émuler une énumération dans Go.
Réponses:
Citant des spécifications linguistiques: Iota
Donc, votre code pourrait être comme
ou
si vous voulez que les bases soient un type distinct de int.
la source
Ord(Base)
n'est donc pas limité à0..3
mais a les mêmes limites que son type numérique sous-jacent. C'est un choix de conception de langage, compromis entre sécurité et performance. Envisagez à chaque fois des vérifications liées au temps d'exécution "en toute sécurité" lorsque vous touchez uneBase
valeur saisie. Ou comment définir le comportement de «débordement» de laBase
valeur pour l'arithmétique et pour++
et--
? Etc.iota + 1
pour ne pas commencer à 0.En vous référant à la réponse de jnml, vous pouvez empêcher de nouvelles instances de type Base en n'exportant pas du tout le type Base (c'est-à-dire l'écrire en minuscules). Si nécessaire, vous pouvez créer une interface exportable qui a une méthode qui renvoie un type de base. Cette interface pourrait être utilisée dans des fonctions de l'extérieur qui traitent des bases, c'est-à-dire
L'intérieur du package principal
a.Baser
est désormais comme une énumération. Ce n'est qu'à l'intérieur d'un package que vous pouvez définir de nouvelles instances.la source
base
n'est utilisée que comme récepteur de méthode. Si votrea
package exposait une fonction prenant un paramètre de typebase
, cela deviendrait dangereux. En effet, l'utilisateur pourrait simplement l'appeler avec la valeur littérale 42, que la fonction accepterait commebase
puisqu'elle peut être castée en entier. Pour éviter cela, fairebase
unstruct
:type base struct{value:int}
. Problème: vous ne pouvez plus déclarer les bases comme constantes, uniquement les variables de module. Mais 42 ne seront jamais convertis en unbase
de ce type.Vous pouvez le faire ainsi:
Avec ce compilateur de code devrait vérifier le type d'énumération
la source
Il est vrai que les exemples ci-dessus d'utilisation de
const
etiota
sont les façons les plus idiomatiques de représenter des énumérations primitives dans Go. Mais que se passe-t-il si vous cherchez un moyen de créer une énumération plus complète similaire au type que vous verriez dans un autre langage comme Java ou Python?Un moyen très simple de créer un objet qui commence à ressembler à une énumération de chaînes en Python serait:
Supposons que vous vouliez également des méthodes utilitaires, comme
Colors.List()
etColors.Parse("red")
. Et vos couleurs étaient plus complexes et devaient être une structure. Ensuite, vous pourriez faire quelque chose comme ceci:À ce stade, bien sûr, cela fonctionne, mais vous pourriez ne pas aimer la façon dont vous devez définir les couleurs de manière répétitive. Si à ce stade, vous souhaitez éliminer cela, vous pouvez utiliser des balises sur votre structure et faire quelques réflexions pour le configurer, mais j'espère que cela suffit pour couvrir la plupart des gens.
la source
Depuis Go 1.4, l'
go generate
outil a été introduit avec lastringer
commande qui rend votre énumération facilement débogable et imprimable.la source
Je suis sûr que nous avons ici beaucoup de bonnes réponses. Mais, j'ai juste pensé à ajouter la façon dont j'ai utilisé les types énumérés
C'est de loin l'un des moyens idiomatiques que nous pourrions créer des types énumérés et utiliser dans Go.
Éditer:
Ajout d'une autre façon d'utiliser les constantes pour énumérer
la source
Voici un exemple qui s'avérera utile en cas de nombreuses énumérations. Il utilise des structures à Golang et s'appuie sur des principes orientés objet pour les lier tous ensemble dans un petit paquet soigné. Aucun du code sous-jacent ne changera lorsqu'une nouvelle énumération est ajoutée ou supprimée. Le processus est le suivant:
enumeration items
: EnumItem . Il a un type entier et chaîne.enumeration
comme une liste deenumeration items
: Enumenum.Name(index int)
: renvoie le nom de l'index donné.enum.Index(name string)
: renvoie le nom de l'index donné.enum.Last()
: retourne l'index et le nom de la dernière énumérationVoici du code:
la source