如何在golang中检查值是否为iota常数类型?

I have a following type defined using iota in golang.

type StatusType int

const (
    PENDING StatusType = iota
    APPROVED
    REJECTED
)

I want to restrict the value passed in in REST-API to the StatusType. Such that the value should not exceed 0,1,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.)

Assuming you wish for invalid JSON payloads to fail, implement the Unmarshaler interface: https://play.golang.org/p/zuchzQ0vmo

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)

I am also grappled with this issue, since I really want to find some easy way to check if a value passed in is within the right range. The trick I came up with is as following:

type StatusType int

const (
    PENDING StatusType = iota
    APPROVED
    REJECTED
)

func (st StatusType) String() string {
    switch st {
    case PENDING:
        return "STATUS:PENDING"
    case APPROVED:
        return "STATUS:APPROVED"
    case REJECTED:
        return "STATUS:REJECTED"
    defaut:
        return "INVALID"
    }
}

func (st StatusType) IsValid() bool {
    return st.String() != "INVALID"
}

Because I often need to translate the enum value to some meaningful representation, I tend to add a String() to an enum type. The cases cover all legal values, while default path captures the situation where the value is invalid.

Simply put, to check if some value is valid, compare its string representation to default case.

One benefit to my solution is that if another enum value is added in the future, we only need to add a case in String() method. The IsValid() method still works.

Another benefit is that in the case when the range of values aren't continuous, my solution also works. Such as the following definition:

const (
    PENDING  StatusType = 1001
    APPROVED            = 1003
    REJECTED            = 1005
)

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
}

the iota is merely a compiler thing. The code is equivalent to:

const PENDING int = 0
const APPROVED int = 1
...

So to design a function CheckValid() to decide if the value is among the given values. You could either use user6169399's method if your const is in a continuous range. Or you could simply define a var map[YOUR_TYPE_HERE]bool to validate.

func (t YOUR_TYPE) CheckValid(){
    if _, ok:=map[t];ok return true
    else return false
}

Here are another two ways to do it right without 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())
}