781 Stimmen

Was ist eine idiomatische Art der Darstellung von Enums in Go?

Ich versuche, ein vereinfachtes Chromosom darzustellen, das aus N Basen besteht, von denen jede nur eine der folgenden sein kann {A, C, T, G} .

Ich möchte die Einschränkungen mit einem enum formalisieren, aber ich frage mich, was die meisten idiomatischen Weg der Emulation eines enum in Go ist.

24voto

Grokify Punkte 13114

Für einen Anwendungsfall wie diesen kann es sinnvoll sein, eine String-Konstante zu verwenden, damit sie in einen JSON-String umgewandelt werden kann. Im folgenden Beispiel, []Base{A,C,G,T} würde zu ["adenine","cytosine","guanine","thymine"] .

type Base string

const (
    A Base = "adenine"
    C      = "cytosine"
    G      = "guanine"
    T      = "thymine"
)

Bei der Verwendung von iota werden die Werte in Ganzzahlen umgewandelt. Im folgenden Beispiel, []Base{A,C,G,T} würde zu [0,1,2,3] .

type Base int

const (
    A Base = iota
    C
    G
    T
)

Hier ein Beispiel für den Vergleich beider Ansätze:

https://play.golang.org/p/VvkcWvv-Tvj

22voto

Zippo Punkte 14520

Ab Go 1.4 wird die go generate Tool wurde zusammen mit dem stringer Befehl, der Ihr Enum leicht debuggbar und druckbar macht.

19voto

wandermonk Punkte 5810

Ich bin mir sicher, dass wir hier eine Menge guter Antworten haben. Aber ich dachte gerade daran, die Art und Weise, wie ich Aufzählungstypen verwendet habe, hinzuzufügen

package main

import "fmt"

type Enum interface {
    name() string
    ordinal() int
    values() *[]string
}

type GenderType uint

const (
    MALE = iota
    FEMALE
)

var genderTypeStrings = []string{
    "MALE",
    "FEMALE",
}

func (gt GenderType) name() string {
    return genderTypeStrings[gt]
}

func (gt GenderType) ordinal() int {
    return int(gt)
}

func (gt GenderType) values() *[]string {
    return &genderTypeStrings
}

func main() {
    var ds GenderType = MALE
    fmt.Printf("The Gender is %s\n", ds.name())
}

Dies ist bei weitem eine der idiomatischsten Möglichkeiten, wie wir Enumerated-Typen erstellen und in Go verwenden können.

編集する:

Hinzufügen einer weiteren Möglichkeit zur Verwendung von Konstanten zur Aufzählung

package main

import (
    "fmt"
)

const (
    // UNSPECIFIED logs nothing
    UNSPECIFIED Level = iota // 0 :
    // TRACE logs everything
    TRACE // 1
    // INFO logs Info, Warnings and Errors
    INFO // 2
    // WARNING logs Warning and Errors
    WARNING // 3
    // ERROR just logs Errors
    ERROR // 4
)

// Level holds the log level.
type Level int

func SetLogLevel(level Level) {
    switch level {
    case TRACE:
        fmt.Println("trace")
        return

    case INFO:
        fmt.Println("info")
        return

    case WARNING:
        fmt.Println("warning")
        return
    case ERROR:
        fmt.Println("error")
        return

    default:
        fmt.Println("default")
        return

    }
}

func main() {

    SetLogLevel(INFO)

}

9voto

Hier ein Beispiel, das sich als nützlich erweist, wenn es viele Aufzählungen gibt. Es verwendet Strukturen in Golang und stützt sich auf objektorientierte Prinzipien, um sie alle in einem ordentlichen kleinen Bündel zusammenzubinden. Keiner der zugrundeliegenden Codes wird sich ändern, wenn eine neue Aufzählung hinzugefügt oder gelöscht wird. Der Prozess ist:

  • Definieren Sie eine Aufzählungsstruktur für enumeration items : EnumItem . Sie hat einen Integer- und einen String-Typ.
  • Definieren Sie die enumeration als eine Liste von enumeration items : Enum
  • Erstellen Sie Methoden für die Aufzählung. Einige davon sind bereits enthalten:
    • enum.Name(index int) Gibt den Namen für den angegebenen Index zurück.
    • enum.Index(name string) Gibt den Namen für den angegebenen Index zurück.
    • enum.Last() Index: Gibt den Index und den Namen der letzten Aufzählung zurück.
  • Fügen Sie Ihre Aufzählungsdefinitionen hinzu.

Hier ist etwas Code:

type EnumItem struct {
    index int
    name  string
}

type Enum struct {
    items []EnumItem
}

func (enum Enum) Name(findIndex int) string {
    for _, item := range enum.items {
        if item.index == findIndex {
            return item.name
        }
    }
    return "ID not found"
}

func (enum Enum) Index(findName string) int {
    for idx, item := range enum.items {
        if findName == item.name {
            return idx
        }
    }
    return -1
}

func (enum Enum) Last() (int, string) {
    n := len(enum.items)
    return n - 1, enum.items[n-1].name
}

var AgentTypes = Enum{[]EnumItem{{0, "StaffMember"}, {1, "Organization"}, {1, "Automated"}}}
var AccountTypes = Enum{[]EnumItem{{0, "Basic"}, {1, "Advanced"}}}
var FlagTypes = Enum{[]EnumItem{{0, "Custom"}, {1, "System"}}}

6voto

XDS Punkte 3083

Umgestaltet https://stackoverflow.com/a/17989915/863651 um sie etwas lesbarer zu machen:

package SampleEnum

type EFoo int

const (
    A EFoo = iota
    C
    T
    G
)

type IEFoo interface {
    Get() EFoo
}

func(e EFoo) Get() EFoo { // every EFoo must fulfill the IEFoo interface
    return e
}

func(e EFoo) otherMethod()  { // "private"
    //some logic
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X