709 votes

Qu'est-ce qu'une manière idiomatique de représenter des enums dans golang?

J'essaie de représenter un chromosome simplifié, constitué de N bases, dont chacune ne peut être que l'une des {A, C, T, G}. Je voudrais formaliser les contraintes avec une énumération, mais je me demande quelle est la façon la plus idiomatique d'émuler une énumération dans go / golang.

840voto

zzzz Points 23017

Des citations de la langue spécifications:Iota

Dans une déclaration de constante, la predeclared identificateur iota représente successives non des constantes entières. Il est remis à 0 à chaque fois que le mot réservé const apparaît dans la source et est incrémenté après chaque ConstSpec. Il peut être utilisé pour construire un ensemble de constantes:

const (  // iota is reset to 0
        c0 = iota  // c0 == 0
        c1 = iota  // c1 == 1
        c2 = iota  // c2 == 2
)

const (
        a = 1 << iota  // a == 1 (iota has been reset)
        b = 1 << iota  // b == 2
        c = 1 << iota  // c == 4
)

const (
        u         = iota * 42  // u == 0     (untyped integer constant)
        v float64 = iota * 42  // v == 42.0  (float64 constant)
        w         = iota * 42  // w == 84    (untyped integer constant)
)

const x = iota  // x == 0 (iota has been reset)
const y = iota  // y == 0 (iota has been reset)

Au sein d'une ExpressionList, la valeur de chaque iota est le même, car il n'est incrémenté après chaque ConstSpec:

const (
        bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0
        bit1, mask1                           // bit1 == 2, mask1 == 1
        _, _                                  // skips iota == 2
        bit3, mask3                           // bit3 == 8, mask3 == 7
)

Ce dernier exemple exploits de l'implicite répétition de la dernière non-vide d'expression de la liste.


Ainsi, votre code peut être comme

const (
        A = iota
        C
        T
        G
)

ou

type Base int

const (
        A Base = iota
        C
        T
        G
)

si vous voulez les bases pour être un type distinct de int.

111voto

metakeule Points 894

Se référant à la réponse de jnml, vous pouvez prévenir de nouvelles instances de type de Base par ne pas exporter le type de Base à tous (c'est à dire de l'écrire en minuscules). Si nécessaire, vous pouvez faire un exportables à l'interface qui a une méthode qui retourne un type de base, de sorte que cette interface peut être utilisée dans les fonctions de l'extérieur que de traiter avec les Bases, c'est à dire

package a

type base int

const (
    A base = iota
    C
    T
    G
)


type Baser interface {
    Base() base
}

// every base must fullfill the Baser interface
func(b base) Base() base {
    return b
}


func(b base) OtherMethod()  {
}

package main

import "a"

// func from the outside that handles a.base via a.Baser
// since a.base is not exported, only exported bases that are created within package a may be used, like a.A, a.C, a.T. and a.G
func HandleBasers(b a.Baser) {
    base := b.Base()
    base.OtherMethod()
}


// func from the outside that returns a.A or a.C, depending of condition
func AorC(condition bool) a.Baser {
    if condition {
       return a.A
    }
    return a.C
}

À l'intérieur du paquet principal une.Cornes est effectivement comme un enum maintenant. Seulement à l'intérieur des paquets, vous pouvez définir de nouvelles instances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X