Home > Software engineering >  Is there a way to check if value satisfies type constraint defined in interface?
Is there a way to check if value satisfies type constraint defined in interface?

Time:08-03

For example I defined the following interface:

type MyTypeConstraint interface {
    ~int | ~string
}

Is there a way to check if given value satisfies this constraint aside from comparing value to each type inside MyTypeConstraint using switch reflect.TypeOf(v) statement? For example, here I don't want user to pass v which type doesn't satisfy constraint into function:

type ErrNode struct {
    Data map[string]interface{}
    // Err  error -- irrelevant
    // next *ErrNode -- irrelevant
}

// `GetData()` is constrained but `Set()` is not.
// Of course I could pass `ErrNode` as parameter into `Set()` 
// like bellow but then I won't be able to chain `Set()` calls.
func GetData[T ErrData](list *ErrNode, k string) (v T, ok bool) {
    v, ok = list.Data[k].(T)
    return v, ok
}

func (e *ErrNode) Set(k string, v interface{}) (self *ErrNode) {
    e.Data[k] = v // v must be of type listed in `MyTypeConstraint`
    return e
}

CodePudding user response:

You cannot (at least with go 1.18 or 1.19 *) put a type constraint on a method:

//syntax error: method must have no type parameters

func (e *ErrNode) Set[T MyTypeConstraint](k string, v T) (self *ErrNode) {
    e.Data[k] = v
    return e
}

You may put a type constraint on a function:

func Setter[T MyTypeConstraint](e *ErrNode, k string, v T) {
    e.Data[k] = v
}

(*) from the go 1.18 release notes: We hope to remove this restriction in a future release. - and this still is not allowed as of go 1.19:

The Go compiler only supports calling a method m on a value x of type parameter type P if m is explicitly declared by P's constraint interface. Similarly, method values x.m and method expressions P.m also are only supported if m is explicitly declared by P, even though m might be in the method set of P by virtue of the fact that all types in P implement m. We hope to remove this restriction in a future release.

  • Related