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

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


当前回答

此外,这是在一个字节的一个位置存储不同角色的一种非常有效的方法,其中第一个值被设置为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)

}

其他回答

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

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
}

对于这样的用例,使用字符串常量可能很有用,这样就可以将其封送到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

从Go 1.4开始,Go生成工具已经与stringer命令一起引入,使枚举易于调试和打印。

有一种方法是使用struct命名空间。

这样做的好处是所有枚举变量都在特定的名称空间下,以避免污染。 问题是我们只能用var而不能用const

type OrderStatusType string

var OrderStatus = struct {
    APPROVED         OrderStatusType
    APPROVAL_PENDING OrderStatusType
    REJECTED         OrderStatusType
    REVISION_PENDING OrderStatusType
}{
    APPROVED:         "approved",
    APPROVAL_PENDING: "approval pending",
    REJECTED:         "rejected",
    REVISION_PENDING: "revision pending",
}

我找到了一个更简单的方法。

const (
Stake TX = iota
Withdraw)


type TX int

func (t TX) String() string {
return [...]string{"STAKE", "WITHDRAW"}[t]}

log.Println(Stake.String()) --> STAKE