How to check whether the value is of type iota constant in Golang?
Solution 1
I do this way:
first create a package named "StatusType" (inside a folder named StatusType):
filename: $GOPATH/enum/StatusType/StatusType.go
package StatusType
type Int int
const (
Pending Int = iota
Approved
Rejected
end
)
func IsValid(value int) bool {
return value < int(end)
}
and use like this ($GOPATH/enum/main.go):
package main
import (
"enum/StatusType"
"fmt"
)
func Test(enum StatusType.Int) {
fmt.Println(enum) //1
}
func main() {
Test(StatusType.Approved)
fmt.Println(StatusType.IsValid(1)) //true
fmt.Println(StatusType.IsValid(10)) //false
}
The StatusType package just exports what you need so there is no need to check against iota const range.
Just in case you want to check, use: StatusType.IsValid()
And nice thing about StatusType package is:
When you want function parameter of StatusType type use StatusType.Int and it reveals that it is enumeration of type int.
Like:
Test(StatusType.Approved)
Solution 2
Simply don't export StatusType
(assuming you define it in package 'status
').
This follow "What is an idiomatic way of representing enums in Go?":
type statusType int
const (
PENDING statusType = iota
APPROVED
REJECTED
)
type StatusTyper interface {
StatusType() statusType
}
func(st statusType) StatusType() statusType {
return st
}
Any external package would then refer to StatusType
-like variable as status.PENDING
, status.APPROVED
or status.REJECTED
.
(the only three statusType
which implement the StatusTyper
interface. Caveat applies.)
Solution 3
Assuming you wish for invalid JSON payloads to fail, implement the Unmarshaler interface: https://play.golang.org/p/zuchzQ0vmo
Solution 4
use go generate with github.com/alvaroloes/enumer
package main
import "fmt"
//go:generate enumer -type=StatusType
type StatusType int
const (
PENDING StatusType = iota
APPROVED
REJECTED
)
func main() {
fmt.Println(StatusType(0).IsAStatusType()) // true
fmt.Println(StatusType(1).IsAStatusType()) // true
fmt.Println(StatusType(2).IsAStatusType()) // true
fmt.Println(StatusType(3).IsAStatusType()) // false
}
![Shamsher](https://i.stack.imgur.com/ZY0v7.jpg?s=256&g=1)
Shamsher
Updated on June 12, 2022Comments
-
Shamsher about 2 years
I have the following type defined using iota in Golang.
type StatusType int const ( PENDING StatusType = iota APPROVED REJECTED )
I want to restrict the value passed in REST-API to the StatusType. Such that the value should not exceed 0,1,2.
-
basgys about 8 yearsDetail not related to your question, but constants should not be uppercased (C style). It is Pending/Approved/Rejected
-
icza about 8 yearsPossible duplicate of Golang: Creating a Constant Type and Restricting the Type's Values
-
-
icza about 8 yearsMaking
StatusType
unexported and using an interface won't cut it. See a dirty trick which I presented in Golang: Creating a Constant Type and Restricting the Type's Values which allows to implement interfaces even with unexported methods. In fact, no constant type can be restricted this way. -
VonC about 8 years@icza Agree (and upvoted). I thought about unexported wrapper struct, but I want to stay as close as possible to the original code of the OP. As I say in the answer, "caveat applies".
-
makapuf over 3 yearsI think -1 would be considered valid
-
Avishay28 about 2 yearswhat if someone decide to put another value after
REJECTED
?