登录
首页 >  Golang >  Go问答

GO语言中的状态表示

来源:stackoverflow

时间:2024-02-26 22:42:26 434浏览 收藏

目前golang学习网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《GO语言中的状态表示》,也希望能帮助到大家,如果阅读完后真的对你学习Golang有帮助,欢迎动动手指,评论留言并分享~

问题内容

我们一般使用枚举来表示状态。

例如,在 python 中:我们这样做

class queuestate(enum):
    enqueued = 1
    processing = 2
    processed = 3
    dequeued = 4

我们可以使用 queuestate.enqueued 等来访问它们。其他语言中也存在同样的行为,例如 java、c# 等。我的意思是这些状态有点绑定在 queuestate 内。

但是当涉及到在go中声明状态时,我们使用const和iota,例如:

type queuestate int

const (
    enqueued queuestate = iota
    processing
    processed
    dequeued
)

我发现这些状态(入队、处理等)与 queuestate 类型没有绑定。

要访问它们,我只需将它们用作常量变量。

例如:

fmt.Println(Enqueued) // prints 0

有没有办法可以将这些状态绑定到类型中并将它们视为枚举,就像我们在其他编程语言中所做的那样? 例如:我想使用它们,比如 queuestate.enqueued


解决方案


我发现这些状态(入队、处理等)与 queuestate 类型没有绑定。

这并不完全正确。当您打印其值时,您会看到打印出 0,因为这是其数字值。类型 queuestateint 作为其底层类型。但 enqueued 的类型为 queuestate (在 Go Playground 上尝试一下):

fmt.printf("%t", enqueued) // main.queuestate

如果您想“直观地”将其绑定到 queuestate 类型,请将其包含在其名称中:

type queuestate int

const (
    queuestateenqueued queuestate = iota
    queuestateprocessing
    queuestateprocessed
    queuestatedequeued
)

然后当提到:queuestateenqueued时,它就变得显而易见了。这种命名“技术”在标准库中广泛使用,net/http 包中的一些示例:

const (
        methodget     = "get"
        methodhead    = "head"
        methodpost    = "post"
        ...
)

const (
        statuscontinue           = 100 // rfc 7231, 6.2.1
        statusswitchingprotocols = 101 // rfc 7231, 6.2.2
        statusprocessing         = 102 // rfc 2518, 10.1

        statusok                   = 200 // rfc 7231, 6.3.1
        statuscreated              = 201 // rfc 7231, 6.3.2
        ...
)

如果您想要人类可读的打印值,请为其定义一个 string() string 方法:

type queuestate int

func (s queuestate) string() string {
    switch s {
    case queuestateenqueued:
        return "enqueued"
    case queuestateprocessing:
        return "processing"
    case queuestateprocessed:
        return "processed"
    case queuestatedequeued:
        return "dequeued"
    }
    return ""
}

然后打印时(在Go Playground上试试):

fmt.println(queuestateenqueued) // prints enqueued

是的,提供这个 string() 方法并保持更新并不是很方便,因此为什么存在像 stringer 这样的工具。他们以比上面的示例实现更紧凑、更高效的方式生成此 string() 方法。

还可以选择使用 string 作为枚举的基础类型,并且枚举值将用作字符串表示形式,而无需 string() 方法(在 Go Playground 上尝试):

type QueueState string

const (
    QueueStateEnqueued   QueueState = "Enqueued"
    QueueStateProcessing QueueState = "Processing"
    QueueStateProcessed  QueueState = "Processed"
    QueueStateDequeued   QueueState = "Dequeued"
)

func main() {
    fmt.Println(QueueStateEnqueued) // prints Enqueued
}

另请注意,当其他人引用您的枚举值时,他们会使用包名称。因此,您可以将枚举常量放在指定的包中,例如称为 queuestate,然后你可以将常量命名为 enqueuedprocessing 等,但当引用它们时,它将采用 queuestate.enqueuedqueuestate.processing 等形式。

另请注意,仅使用常量无法限制类型的值。详情请参见Creating a Constant Type and Restricting the Type's Values

今天关于《GO语言中的状态表示》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>