我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。
我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。
我试图表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{a, C, T, G}中的一个。
我想用枚举形式化约束,但我想知道在Go中模拟枚举的最惯用的方式是什么。
当前回答
这是在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]
其他回答
你可以这样做:
type MessageType int32
const (
TEXT MessageType = 0
BINARY MessageType = 1
)
使用此代码,编译器应该检查枚举类型
我以这种方式创建枚举。假设我们需要一个表示性别的枚举。取值包括“男性”、“女性”、“其他”
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命令一起引入,使枚举易于调试和打印。
重构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
}