我们通常使用枚举来表示状态。

例如,在python中:

class QueueState(Enum):
    Enqueued = 1
    Processing = 2
    Processed = 3
    Dequeued = 4

而且,我们可以使用QueueState.Enqueued等访问它们。在Java,C#等其他语言中也存在相同的行为。我的意思是,这些状态在QueueState中绑定(bind)。

但是当涉及到声明状态时,我们使用const和iota,例如:
type QueueState int

const (
    Enqueued QueueState = iota
    Processing
    Processed
    Dequeued
)

我看到这些类型QueueState没有绑定(bind)(入队,正在处理等)状态。

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

例如:
fmt.Println(Enqueued) // prints 0

有没有办法像我在其他编程语言中那样将这些状态绑定(bind)为一个类型并将它们视为枚举?
例如:我想使用像QueueState.Enqueued这样的名称

最佳答案



这不是完全正确的。当您打印其值时,您会看到0被打印,因为那是其数值。 QueueState类型具有int作为其基础类型。但是EnqueuedQueueState类型的(请在Go Playground上尝试):

fmt.Printf("%T", Enqueued) // main.QueueState

如果要“可视地”将其绑定(bind)到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

09-11 18:31