What is an idiomatic way of representing enums in Go?
我试图表示一个简化的染色体,它由n个碱基组成,每个碱基只能是
我想用枚举形式化约束,但我想知道模仿枚举的最惯用方法是什么。
引证:将从语言规格
Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. It is reset to 0 whenever the reserved word const appears in the source and increments after each ConstSpec. It can be used to construct a set of related constants:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | const ( // iota is reset to 0 c0 = iota // c0 == 0 c1 = iota // c1 == 1 c2 = iota // c2 == 2 ) const ( a = 1 << iota // a == 1 (iota has been reset) b = 1 << iota // b == 2 c = 1 << iota // c == 4 ) const ( u = iota * 42 // u == 0 (untyped integer constant) v float64 = iota * 42 // v == 42.0 (float64 constant) w = iota * 42 // w == 84 (untyped integer constant) ) const x = iota // x == 0 (iota has been reset) const y = iota // y == 0 (iota has been reset) |
Within an ExpressionList, the value of each iota is the same because it is only incremented after each ConstSpec:
1 2 3 4 5 6 | const ( bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0 bit1, mask1 // bit1 == 2, mask1 == 1 _, _ // skips iota == 2 bit3, mask3 // bit3 == 8, mask3 == 7 ) |
This last example exploits the implicit repetition of the last non-empty expression list.
那么你的代码可能是样
1 2 3 4 5 6 | const ( A = iota C T G ) |
或
1 2 3 4 5 6 7 8 | type Base int const ( A Base = iota C T G ) |
如果你想使用一个单独的类型是int。
指酒店在jnml应答新的实例,你可以防止由输出基地,基地型困难型(IU写它在所有小写)。如果需要,你可以作出exportable接口,有一个方法返回a库类型。这个接口可以被用在函数的外面是在处理基地。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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() { } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 } |
在主包
为1.4),已在
你可以这样做:
1 2 3 4 5 6 | type MessageType int32 const ( TEXT MessageType = 0 BINARY MessageType = 1 ) |
这一类型的枚举代码编译器不检查
这是真的,上面的例子是使用
一个非常简单的方法来创建一个对象的外观和感觉像一起飞在Python字符串的枚举类型是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package main import ( "fmt" ) var Colors = newColorRegistry() func newColorRegistry() *colorRegistry { return &colorRegistry{ Red: "red", Green:"green", Blue: "blue", } } type colorRegistry struct { Red string Green string Blue string } func main() { fmt.Println(Colors.Red) } |
想你想的一些实用方法,样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package main import ( "errors" "fmt" ) var Colors = newColorRegistry() type Color struct { StringRepresentation string Hex string } func (c *Color) String() string { return c.StringRepresentation } func newColorRegistry() *colorRegistry { red := &Color{"red","F00"} green := &Color{"green","0F0"} blue := &Color{"blue","00F"} return &colorRegistry{ Red: red, Green: green, Blue: blue, colors: []*Color{red, green, blue}, } } type colorRegistry struct { Red *Color Green *Color Blue *Color colors []*Color } func (c *colorRegistry) List() []*Color { return c.colors } func (c *colorRegistry) Parse(s string) (*Color, error) { for _, color := range c.List() { if color.String() == s { return color, nil } } return nil, errors.New("couldn't find it") } func main() { fmt.Printf("%s ", Colors.List()) } |
在那点上,知道它,但你可能不喜欢你要repetitively定义的颜色。在这一点,如果你喜欢,你可以消除使用的标签,在你做一些漂亮的结构和它的反射到集,但希望这是足以覆盖大多数的人。
我知道我们有很多很好的答案在这里。但是,我只是想说我所用的方式enumerated类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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 ", ds.name()) } |
这是由一个idiomatic远的方式,我们可以创建和使用enumerated类型中去。
编辑:
另一种方式使用的常量添加到使用enumerate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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) } |