I see there is no binding of these states (Enqueued, Processing, etc) with the type QueueState
.
This is not completely true. When you print its value, you see 0
printed because that's its numerical value. The type QueueState
has int
as its underlying type. But Enqueued
is of type QueueState
(try it on the Go Playground):
fmt.Printf("%T", Enqueued) // main.QueueState
If you want to "visually" bound it to the QueueState
type, include it in its name:
type QueueState int
const (
QueueStateEnqueued QueueState = iota
QueueStateProcessing
QueueStateProcessed
QueueStateDequeued
)
Then when it is referred: QueueStateEnqueued
it becomes obvious. This naming "technique" is widely used in the standard library, some examples from the net/http
package:
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
...
)
If you want human-readable printed value, define a String() string
method for it:
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 ""
}
Then when printed (try it on the Go Playground):
fmt.Println(QueueStateEnqueued) // prints Enqueued
Yes, it's not very convenient to provide this String()
method and keep it updated, hence why tools like stringer
exist. They generate this String()
method in a more compact and efficient way than the above example implementation.
There's also the option to use string
as the enum's underlying type, and the enum values will serve as the string representation without the String()
method (try it on the 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
}
Also note that when others refer to your enum values, they do so using the package name. So you may place the enum constants in their designated package, e.g. called queuestate
, and then you may name your constants just Enqueued
, Processing
etc, but when they are referred to, it will be in the form of queuestate.Enqueued
, queuestate.Processing
etc.
Also note that using constants only you can't restrict the values of your type. For details, see Creating a Constant Type and Restricting the Type's Values.