我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。
我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。
我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。
我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。
当前回答
有一种方法是使用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",
}
其他回答
有一种方法是使用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
重构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
}
从Go 1.4开始,Go生成工具已经与stringer命令一起引入,使枚举易于调试和打印。
参考jnml的答案,您可以通过根本不导出Base类型来防止创建Base类型的新实例(即将其写成小写)。如果需要,您可以创建一个具有返回基类型的方法的可导出接口。这个接口可以用在处理base的外部函数中。
package a
type base int
const (
A base = iota
C
T
G
)
type Baser interface {
Base() base
}
// every base must fulfill 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
}
在主包中,a.b eser现在实际上就像一个枚举。 只有在a包中才能定义新实例。