博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在Go中表示枚举的惯用方法是什么?
阅读量:2379 次
发布时间:2019-05-10

本文共 5757 字,大约阅读时间需要 19 分钟。

本文翻译自:

I'm trying to represent a simplified chromosome, which consists of N bases, each of which can only be one of {A, C, T, G} . 我试图代表一个简化的染色体,它由N个碱基组成,每个碱基只能是{A, C, T, G}

I'd like to formalize the constraints with an enum, but I'm wondering what the most idiomatic way of emulating an enum is in Go. 我想用枚举来形式化约束,但我想知道在Go中模仿枚举的最惯用方法是什么。


#1楼

参考:


#2楼

Quoting from the language specs: 引用语言规范:

Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. 在常量声明中,预先声明的标识符iota表示连续的无类型整数常量。 It is reset to 0 whenever the reserved word const appears in the source and increments after each ConstSpec. 每当保留字const出现在源中并在每个ConstSpec之后递增时,它将复位为0。 It can be used to construct a set of related constants: 它可以用于构造一组相关的常量:

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: 在ExpressionList中,每个iota的值都是相同的,因为它只在每个ConstSpec之后递增:

const (        bit0, mask0 = 1 << iota, 1<

This last example exploits the implicit repetition of the last non-empty expression list. 最后一个示例利用最后一个非空表达式列表的隐式重复。


So your code might be like 所以你的代码可能就像

const (        A = iota        C        T        G)

or 要么

type Base intconst (        A Base = iota        C        T        G)

if you want bases to be a separate type from int. 如果你想base和int是一个单独的类型。


#3楼

Referring to the answer of jnml, you could prevent new instances of Base type by not exporting the Base type at all (ie write it lowercase). 参考jnml的答案,您可以通过根本不导出Base类型来防止Base类型的新实例(即将其写为小写)。 If needed, you may make an exportable interface that has a method that returns a base type. 如果需要,您可以创建一个可导出的接口,该接口具有返回基本类型的方法。 This interface could be used in functions from the outside that deal with Bases, ie 该接口可以用于处理Bases的外部函数,即

package atype base intconst (    A base = iota    C    T    G)type Baser interface {    Base() base}// every base must fulfill the Baser interfacefunc(b base) Base() base {    return b}func(b base) OtherMethod()  {}

package mainimport "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.Gfunc HandleBasers(b a.Baser) {    base := b.Base()    base.OtherMethod()}// func from the outside that returns a.A or a.C, depending of conditionfunc AorC(condition bool) a.Baser {    if condition {       return a.A    }    return a.C}

Inside the main package a.Baser is effectively like an enum now. 在主包内, a.Baser现在实际上就像一个枚举。 Only inside the a package you may define new instances. 只有在包中,您才可以定义新实例。


#4楼

从Go 1.4开始, go generate工具与命令一起引入,使得enum易于调试和打印。


#5楼

You can make it so: 你可以这样做:

type MessageType int32const (    TEXT   MessageType = 0    BINARY MessageType = 1)

With this code compiler should check type of enum 使用此代码编译器应检查枚举的类型


#6楼

It's true that the above examples of using const and iota are the most idiomatic ways of representing primitive enums in Go. 确实,上面使用constiota例子是在Go中表示原始枚举的最惯用的方式。 But what if you're looking for a way to create a more fully-featured enum similar to the type you'd see in another language like Java or Python? 但是,如果您正在寻找一种方法来创建一个类似于您在另一种语言(如Java或Python)中看到的类型的功能更全面的枚举,该怎么办?

A very simple way to create an object that starts to look and feel like a string enum in Python would be: 创建一个开始在Python中看起来像字符串枚举的对象的一种非常简单的方法是:

package mainimport (    "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)}

Suppose you also wanted some utility methods, like Colors.List() , and Colors.Parse("red") . 假设您还需要一些实用工具方法,如Colors.List()Colors.Parse("red") And your colors were more complex and needed to be a struct. 你的颜色更复杂,需要成为一个结构。 Then you might do something a bit like this: 然后你可能会做一些像这样的事情:

package mainimport (    "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\n", Colors.List())}

At that point, sure it works, but you might not like how you have to repetitively define colors. 在这一点上,确定它有效,但你可能不喜欢你必须重复定义颜色。 If at this point you'd like to eliminate that, you could use tags on your struct and do some fancy reflecting to set it up, but hopefully this is enough to cover most people. 如果此时你想消除它,你可以在你的结构上使用标签并做一些反思来设置它,但希望这足以覆盖大多数人。

转载地址:http://cyexb.baihongyu.com/

你可能感兴趣的文章
Redis 基础命令 --- Hash篇
查看>>
Redis 基础命令 --- List篇
查看>>
Redis 基础命令 --- Set篇
查看>>
Redis数据库篇 -- 生存时间
查看>>
面向对象设计基本原则
查看>>
Redis数据库篇 -- 事务
查看>>
hadoop 完全分布式环境搭建
查看>>
HDFS 回收站
查看>>
hadoop 完全分布式HA高可用集群(手工切换)搭建
查看>>
hadoop 完全分布式HA高可用集群(自动切换)搭建
查看>>
Hbase shell常见命令
查看>>
看看这同一句sql,scan index占用的资源大了很多!!
查看>>
couldn't set locale correctly报错解决
查看>>
回收基表的空间,造成物化视图只刷新了一部分数据
查看>>
ORA-12052,不能建立快速刷新物化视图的解决
查看>>
物化视图comlete刷新会产生大量的日志
查看>>
Mysql cluster slave server的自动检测与修复
查看>>
solaris同步时钟
查看>>
mysql升级
查看>>
V$sql_text v$sqlarea v$sql 的区别
查看>>