我在 Golang 中使用 iota 定义了以下类型。
type StatusType int
const (
PENDING StatusType = iota
APPROVED
REJECTED
)
我希望限制在REST API中传递的值为StatusType。这样,该值不应超过0、1、2。
我是这样做的:
首先创建一个名为"StatusType"的包(在名为StatusType的文件夹中):
文件名:$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)
}
使用方法如下($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
}
StatusType 包只导出您需要的内容,因此无需针对 iota const 范围进行检查。
以防万一要检查,请使用:StatusType.IsValid()
而 StatusType 包的好处之一是:
当您想要 StatusType 类型的函数参数时,请使用 StatusType.Int,并且它会显示它是 int 类型的枚举类型。
像这样:
Test(StatusType.Approved)
简单来说,如果你在'status
'包中定义了StatusType
,那么就不要导出它。
type statusType int
const (
PENDING statusType = iota
APPROVED
REJECTED
)
type StatusTyper interface {
StatusType() statusType
}
func(st statusType) StatusType() statusType {
return st
}
StatusType
的变量,例如status.PENDING
、status.APPROVED
或status.REJECTED
。statusType
是实现StatusTyper
接口的唯一选项。 注意事项。)StatusType
变为未公开的并使用接口是不够的。请参见我在 Golang: Creating a Constant Type and Restricting the Type's Values 中提出的一个小技巧,它允许实现即使具有未公开方法的接口。事实上,没有任何常量类型可以以这种方式受限制。 - icza这里有另外两种不使用map的正确方法: https://play.golang.org/p/eKW_KPshx7b
package main
import (
"errors"
"log"
)
type StatusType int
const (
PENDING StatusType = iota
APPROVED
REJECTED
)
func Validate(val int) (bool, error) {
if v := StatusType(val); v > REJECTED || v < PENDING {
return false, errors.New("invalid StatusType")
}
return true, nil
}
func (t StatusType) Validate() (bool, error) {
if t > REJECTED || t < PENDING {
return false, errors.New("invalid StatusType")
}
return true, nil
}
func main() {
log.Print(Validate(-1))
log.Print(Validate(0))
log.Print(Validate(1))
log.Print(Validate(3))
log.Print(StatusType(-1).Validate())
log.Print(StatusType(1).Validate())
log.Print(StatusType(10).Validate())
}
使用go generate和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
}
iota 只是编译器的一个东西。代码等同于:
const PENDING int = 0
const APPROVED int = 1
...
func (t YOUR_TYPE) CheckValid(){
if _, ok:=map[t];ok return true
else return false
}