在 Go 中表示枚举的惯用方式是什么?

新手上路,请多包涵

我试图表示一个简化的染色体,它由 N 个碱基组成,每个碱基只能是 {A, C, T, G} 之一。

我想用枚举形式化约束,但我想知道在 Go 中模拟枚举的最惯用的方法是什么。

原文由 carbocation 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 376
2 个回答

引用语言规范: Iota

在常量声明中,预先声明的标识符 iota 表示连续的无类型整数常量。只要保留字 const 出现在源代码中并在每个 ConstSpec 之后递增,它就会重置为 0。它可用于构造一组相关常量:

 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)

在 ExpressionList 中,每个 iota 的值都是相同的,因为它仅在每个 ConstSpec 之后递增:

 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
)

最后一个示例利用了最后一个非空表达式列表的隐式重复。


所以你的代码可能像

const (
        A = iota
        C
        T
        G
)

或者

type Base int

const (
        A Base = iota
        C
        T
        G
)

如果您希望 bases 成为与 int 不同的类型。

原文由 zzzz 发布,翻译遵循 CC BY-SA 3.0 许可协议

参考 jnml 的答案,您可以通过根本不导出 Base 类型(即写成小写)来防止 Base 类型的新实例。如果需要,您可以制作一个可导出接口,该接口具有返回基类型的方法。该接口可用于处理 Bases 的外部函数,即

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.Baser 现在实际上就像一个枚举。只有在包内你可以定义新的实例。

原文由 metakeule 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题