Determine if var is a regular type

How can I determine if the variable passed to my Func is indeed the type I want?

I have a custom type

type Name string

      

and a set of constants of this type

const Fred Name = "fred"

      

and I have a func that I need to disallow any other input type other than my custom ex type:

func MyFunc(name1 Name, name2 Name) (*Person, error) {
//bunch of stuff
}

      

how do i check inside my func that name1 and name2 are not strings passed to func, but exclusively a constant that is already defined in my type ex:

p, err := MyFunc(Fred,Albert) //What i want
p, err := MyFunc("fred","albert") //What i dont want to happen

      

if can't answer my question, how can I make, like Enum in Golang, a type that means something and restrict another ppl to use the type i that I have defined

+3


source to share


2 answers


Short version? you cannot create this limiting kind of enum.

Long version, there are several options:

Define a type-checking function:

func (n Name) valid() bool { //private method
    switch n {
    case Mal, Kaylee: //all the valid constants
        return true
    }
    return false
}

      

However, this does not prevent anyone from using Name("fred").valid()

as stated in @peterSO point.



Use a structure with a private member in it, however they are not "constants" per se, an external package might reassign them to invalid values:

type Name struct {
    n string
}

var (
    invalid = Name{}
    Mal     = Name{"mal"}
    Kaylee  = Name{"kaylee"}
)

func MyFunc(name1 Name, name2 Name) error {
    if name1 == invalid || name2 == invalid {
        return errors.New("invalid names")
    }
    return nil
}

      

Use numeric constants and a private array, this is the only reliable validation version, and the closest you get to a real enum:

type Name uint8

var names = [...]string{
    "Mal",
    "Kaylee",
}

func (n Name) valid() bool {
    return uint8(n) < uint8(len(names))
}

func (n Name) String() string {
    if !n.valid() {
        return "invalid"
    }
    return names[n]
} 

const (
    Mal Name = iota
    Kaylee
)

func MyFunc(name1 Name, name2 Name) error {
    if !name1.valid() || !name2.valid() {
        return errors.New("invalid names")
    }
    return nil
}

      

+1


source


your type implements an interface that is not exported



type Name string

type Private interface{
     private()
}

func (n Name) private() {}

func MyFunc(name1, name2 Private) (*Person, error) {
    //bunch of stuff
}

      

+4


source







All Articles