Go 中具有作用域的多组常量名称

我有一个需要无限数量的常量集的 Go 应用程序。该应用程序还要求我能够在运行时将字符串映射到(整数)常量,反之亦然。常量的名称只能保证是有效的标识符,因此几乎可以肯定会有重复的常量名称。特别是,每组常量都有一个称为“无效”的元素。在 C++11 中,我会使用枚举类来实现作用域。在 Python 中,我可能会使用类变量。我正在努力寻找一种在 Go 中表达这一点的惯用方式。我看过的选项包括:


为每组常量使用单独的包。这有很多缺点,因为我宁愿整个集合都在同一个包中,这样我就可以在包级别构建对这些集合的支持,这样我就可以测试整个集合,而不会使测试代码过于复杂一次进行多包测试。

first.go:


package first

type First int

const (

    ConstOne First = iota

    ConstTwo

    Invalid = -1

)


func IntToCode(fi First)string { ... }

func CodeToInt(code string)First { ... }

second.go:


package second

type Second int

const (

    ConstOne Second = iota

    ConstTwo

    Invalid = -1

)


func IntToCode(se Second)string { ... }

func CodeToInt(code string)Second { ... }

example.go:


import (

    "first"

    "second"

)


First fi = first.CodeToInt("ConstOne")

Second se = second.Invalid

对每个常量使用经过验证的全局唯一前缀技术。然而,考虑到集合的数量真的很大,必须使用编码约定从本质上发明和管理一堆命名空间充其量是尴尬的。此选项还迫使我修改常量的名称(这是使用它们的全部意义)。

first.go:


package mypackage


type First int


const (

    FI_CONSTONE First = iota

    FI_CONSTTWO

    FI_INVALID = -1

)


func IntToCode(fi First)string { ... }

func CodeToInt(code string)First { ... }

second.go:


package mypackage


type Second int


const (

    SE_CONSTONE Second = iota

    SE_CONSTTWO

    SE_INVALID = -1

)


func IntToCode(se Second)string { ... }

func CodeToInt(code string)Second { ... }

example.go:


package mypackage


import (

    "first"

    "second"

)


First fi = first.CodeToInt("ConstOne")

Second se = SE_INVALID

什么是更好、更惯用的解决方案?我希望能够说这样的话:


First fi = First.Invalid

但我没有成功地提出一种允许这样做的方法。


杨__羊羊
浏览 170回答 1
1回答

繁星coding

您可以为单独的代码集使用单独的包,并使用单个包来定义与代码关联的更高级别的功能,并为该更高级别的包编写测试。我还没有编译或测试任何这些:例如对于代码集:package product // or whatever namespace is associated with the codesettype Const intconst (    ONE Const = iota    TWO    ...    INVALID = -1)func (c Const) Code() string {    return intToCode(int(c)) // internal implementation}type Code stringconst (     STR_ONE Code = "ONE"     ...)func (c Code) Const() int {    return codeToInt(string(c)) // internal implementation}例如对于更高级别的函数包:// codes.gopackage codestype Coder interface{    Code() string}type Conster interface{    Const() int}func DoSomething(c Coder) string {    return "The code is: " + c.Code()}    // codes_product_test.gopackage codesimport "product"func TestProductCodes(t *testing.T) {    got := DoSomething(product.ONE) // you can pass a product.Const as a Coder    want := "The code is: ONE"    if got != want {        t.Error("got:", got, "want:", want)    }}编辑:要检索特定代码的常量,您可以执行以下操作product.Code("STRCODE").Const()也许最好Const()返回 aCoder以便product.Code("ONE").Const()可以是 a product.Const。我认为如果你玩弄它,有几种选择,并且在某个地方会有一个很好的选择。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go