我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。
我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。
我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。
我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。
当前回答
我以这种方式创建枚举。假设我们需要一个表示性别的枚举。取值包括“男性”、“女性”、“其他”
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
}
其他回答
有一种方法是使用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
你可以这样做:
type MessageType int32
const (
TEXT MessageType = 0
BINARY MessageType = 1
)
使用此代码,编译器应该检查枚举类型
下面是一个示例,当有许多枚举时,它将被证明是有用的。它使用了Golang中的结构,并借鉴了面向对象原则(Object Oriented Principles),将它们紧密地捆绑在一起。添加或删除新的枚举时,底层代码都不会更改。流程如下:
定义枚举项的枚举结构:EnumItem。它有一个整数和字符串类型。 将枚举定义为枚举项列表:Enum 为枚举构建方法。其中包括: 枚举。Name(index int):返回给定索引的名称。 枚举。Index(name string):返回给定索引的名称。 枚举. last():返回最后一个枚举的索引和名称 添加枚举定义。
下面是一些代码:
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"}}}
这是在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]