我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。

我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。


当前回答

我相信我们有很多好的答案。但是,我只是想以使用枚举类型的方式添加

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())
}

这是迄今为止我们创建枚举类型并在Go中使用的惯用方法之一。

编辑:

添加另一种使用常量进行枚举的方法

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)

}

其他回答

此外,这是在一个字节的一个位置存储不同角色的一种非常有效的方法,其中第一个值被设置为1,位移动了一个iota。

package main

import "fmt"

const (
    isCaptain = 1 << iota
    isTrooper
    isMedic

    canFlyMars
    canFlyJupiter
    canFlyMoon
)

func main() {
    var roles byte = isCaptain | isMedic | canFlyJupiter
    //Prints a binary representation.
    fmt.Printf("%b\n", roles)
    fmt.Printf("%b\n", isCaptain)
    fmt.Printf("%b\n", isTrooper)
    fmt.Printf("%b\n", isMedic)

    fmt.Printf("Is Captain? %v\n", isCaptain&roles == isCaptain)
    fmt.Printf("Is Trooper? %v", isTrooper&roles == isTrooper)

}

对于这样的用例,使用字符串常量可能很有用,这样就可以将其封送到JSON字符串中。在下例中,[]碱基{A,C,G,T}将被编组为["腺嘌呤","胞嘧啶","鸟嘌呤","胸腺嘧啶"]。

type Base string

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

当使用iota时,值被封送成整数。在下面的例子中,[]基数{A,C,G,T}将被封送到[0,1,2,3]。

type Base int

const (
    A Base = iota
    C
    G
    T
)

下面是一个比较两种方法的例子:

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

我以这种方式创建枚举。假设我们需要一个表示性别的枚举。取值包括“男性”、“女性”、“其他”

package gender

import (
    "fmt"
    "strings"
)

type Gender struct {
    g string
}

var (
    Unknown = Gender{}
    Male    = Gender{g: "male"}
    Female  = Gender{g: "female"}
    Other   = Gender{g: "other"}
)

var genders = []Gender{
    Unknown,
    Male,
    Female,
    Other,
}

func Parse(code string) (parsed Gender, err error) {
    for _, g := range genders {
        if g.g == strings.ToLower(code) {
            if g == Unknown {
                err = fmt.Errorf("unknown gender")
            }
            parsed = g
            return
        }
    }

    parsed = Unknown
    err = fmt.Errorf("unknown gender", code)
    return
}

func (g Gender) Gender() string {
    return g.g
}

重构https://stackoverflow.com/a/17989915/863651,使其更具可读性:

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
}

这是在golang中实现enum的安全方法:

package main

import (
    "fmt"
)

const (
    MALE   = _gender(1)
    FEMALE = _gender(2)
    RED    = _color("RED")
    GREEN  = _color("GREEN")
    BLUE   = _color("BLUE")
)

type Gender interface {
    _isGender()
    Value() int
}

type _gender int

func (_gender) _isGender() {}

func (_g _gender) Value() int {
    return int(_g)
}

type Color interface {
    _isColor()
    Value() string
}

type _color string

func (_color) _isColor() {}

func (_c _color) Value() string {
    return string(_c)
}

func main() {
    genders := []Gender{MALE, FEMALE}
    colors := []Color{RED, GREEN, BLUE}
    fmt.Println("Colors =", colors)
    fmt.Println("Genders =", genders)
}

输出:

Colors = [RED GREEN BLUE]
Genders = [1 2]