为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中表示状态

在 Go 中表示状态

Go
紫衣仙女 2023-07-10 14:43:51
我们一般使用枚举来表示状态。例如,在 python 中:我们做class QueueState(Enum):    Enqueued = 1    Processing = 2    Processed = 3    Dequeued = 4我们可以使用QueueState.Enqueued等来访问它们。其他语言中也存在同样的行为,例如 Java、C# 等。我的意思是这些状态有点绑定在 中QueueState。但是当涉及到在 go 中声明状态时,我们使用 const 和 iota,例如:type QueueState intconst (    Enqueued QueueState = iota    Processing    Processed    Dequeued)我发现这些状态(入队、处理等)与 type 没有绑定QueueState。要访问它们,我只需将它们用作常量变量。例如:fmt.Println(Enqueued) // prints 0有没有办法可以将这些状态绑定到类型中并将它们视为枚举,就像我们在其他编程语言中所做的那样?例如:我想像这样使用它们QueueState.Enqueued
查看完整描述

1 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

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


这并不完全正确。当您打印它的值时,您会看到0打印的内容,因为这是它的数值。该类型QueueState具有int作为其基础类型。但是Enqueued是类型(在Go PlaygroundQueueState上尝试一下):


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枚举的基础类型,并且枚举值将用作不带该方法的字符串表示形式(在Go PlaygroundString()上尝试):


type QueueState string


const (

    QueueStateEnqueued   QueueState = "Enqueued"

    QueueStateProcessing QueueState = "Processing"

    QueueStateProcessed  QueueState = "Processed"

    QueueStateDequeued   QueueState = "Dequeued"

)


func main() {

    fmt.Println(QueueStateEnqueued) // prints Enqueued

}

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


另请注意,仅使用常量无法限制类型的值。



查看完整回答
反对 回复 2023-07-10
  • 1 回答
  • 0 关注
  • 75 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信